netgescon-day0/app/Services/Anagrafiche/RubricaPhoneLookupService.php

91 lines
3.8 KiB
PHP

<?php
namespace App\Services\Anagrafiche;
use App\Models\RubricaUniversale;
use App\Support\PhoneNumber;
use Illuminate\Support\Facades\Schema;
class RubricaPhoneLookupService
{
public function findByPhone(?string $phone, ?int $adminId = null): ?RubricaUniversale
{
$digits = PhoneNumber::normalizeDigits((string) $phone);
if ($digits === '') {
return null;
}
$tail = strlen($digits) >= 7 ? substr($digits, -7) : $digits;
if ($tail === '') {
return null;
}
foreach ([[$digits, true], [$digits, false], [$tail, true], [$tail, false]] as [$needle, $directFirst]) {
$found = $directFirst
? ($this->directQuery((string) $needle, $adminId)->first() ?: $this->channelQuery((string) $needle, $adminId)->first())
: ($this->channelQuery((string) $needle, $adminId)->first() ?: $this->directQuery((string) $needle, $adminId)->first());
if ($found instanceof RubricaUniversale) {
return $found;
}
}
return null;
}
private function directQuery(string $digits, ?int $adminId)
{
return RubricaUniversale::query()
->when($this->hasAmministratoreColumn() && $adminId && $adminId > 0, function ($query) use ($adminId): void {
$query->where(function ($inner) use ($adminId): void {
$inner->where('amministratore_id', $adminId)
->orWhereNull('amministratore_id');
});
})
->where(function ($query) use ($digits): void {
$query
->orWhereRaw($this->normalizedDigitsSql('telefono_cellulare') . ' LIKE ?', ['%' . $digits . '%'])
->orWhereRaw($this->normalizedDigitsSql('telefono_ufficio') . ' LIKE ?', ['%' . $digits . '%'])
->orWhereRaw($this->normalizedDigitsSql('telefono_casa') . ' LIKE ?', ['%' . $digits . '%']);
if (Schema::hasColumn('rubrica_universale', 'telefono_cellulare_nazionale')) {
$query->orWhereRaw($this->normalizedDigitsSql('telefono_cellulare_nazionale') . ' LIKE ?', ['%' . $digits . '%']);
}
})
->orderByDesc('updated_at')
->orderByDesc('id');
}
private function channelQuery(string $digits, ?int $adminId)
{
if (! Schema::hasTable('rubrica_contatti_canali')) {
return RubricaUniversale::query()->whereRaw('1 = 0');
}
return RubricaUniversale::query()
->select('rubrica_universale.*')
->join('rubrica_contatti_canali as rcc', 'rcc.rubrica_id', '=', 'rubrica_universale.id')
->when($this->hasAmministratoreColumn() && $adminId && $adminId > 0, function ($query) use ($adminId): void {
$query->where(function ($inner) use ($adminId): void {
$inner->where('rubrica_universale.amministratore_id', $adminId)
->orWhereNull('rubrica_universale.amministratore_id');
});
})
->whereIn('rcc.tipo', ['telefono', 'cellulare'])
->whereRaw($this->normalizedDigitsSql('rcc.valore') . ' LIKE ?', ['%' . $digits . '%'])
->orderByDesc('rcc.is_principale')
->orderByDesc('rcc.updated_at')
->orderByDesc('rubrica_universale.updated_at')
->orderByDesc('rubrica_universale.id');
}
private function hasAmministratoreColumn(): bool
{
return Schema::hasColumn('rubrica_universale', 'amministratore_id');
}
private function normalizedDigitsSql(string $column): string
{
return "REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COALESCE({$column}, ''), ' ', ''), '+', ''), '-', ''), '(', ''), ')', '')";
}
}