890 lines
37 KiB
PHP
890 lines
37 KiB
PHP
<?php
|
|
namespace App\Filament\Pages\Condomini;
|
|
|
|
use App\Filament\Pages\Gescon\RubricaUniversaleScheda;
|
|
use App\Filament\Pages\UnitaImmobiliarePage;
|
|
use App\Models\LegacyCondominNominativo;
|
|
use App\Models\RubricaUniversale;
|
|
use App\Models\Stabile;
|
|
use App\Models\UnitaImmobiliare;
|
|
use App\Models\User;
|
|
use App\Support\StabileContext;
|
|
use BackedEnum;
|
|
use Filament\Actions\Action;
|
|
use Filament\Pages\Page;
|
|
use Filament\Tables\Columns\TextColumn;
|
|
use Filament\Tables\Concerns\InteractsWithTable;
|
|
use Filament\Tables\Contracts\HasTable;
|
|
use Filament\Tables\Filters\SelectFilter;
|
|
use Filament\Tables\Filters\TernaryFilter;
|
|
use Filament\Tables\Table;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema as DbSchema;
|
|
use UnitEnum;
|
|
|
|
class NominativiStabile extends Page implements HasTable
|
|
{
|
|
use InteractsWithTable;
|
|
|
|
public ?int $stabileId = null;
|
|
|
|
/** @var array<int, string> */
|
|
private array $rubricaTitoloCache = [];
|
|
|
|
private function applyDomainNominativiSearch(Builder $query, string $search, int $activeStabileId): Builder
|
|
{
|
|
$search = trim($search);
|
|
if ($search == '') {
|
|
return $query;
|
|
}
|
|
|
|
$like = '%' . str_replace(['%', '_'], ['\\%', '\\_'], $search) . '%';
|
|
|
|
$ownerRoles = [
|
|
'condomino',
|
|
'proprietario',
|
|
'comproprietario',
|
|
'nudo_proprietario',
|
|
'usufruttuario',
|
|
'usufrutto',
|
|
];
|
|
$tenantRoles = [
|
|
'inquilino',
|
|
'locatario',
|
|
'conduttore',
|
|
];
|
|
|
|
return $query->where(function (Builder $q) use ($like, $activeStabileId, $ownerRoles, $tenantRoles) {
|
|
$q
|
|
->where('unita_immobiliari.interno', 'like', $like)
|
|
->orWhere('unita_immobiliari.scala', 'like', $like)
|
|
->orWhere('unita_immobiliari.piano', 'like', $like)
|
|
->orWhereExists(function ($sub) use ($like, $activeStabileId, $ownerRoles) {
|
|
$sub
|
|
->selectRaw('1')
|
|
->from('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $activeStabileId)
|
|
->where('rr.is_attivo', true)
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $ownerRoles)
|
|
->where(function ($w) use ($like) {
|
|
$w
|
|
->where('ru.ragione_sociale', 'like', $like)
|
|
->orWhere('ru.nome', 'like', $like)
|
|
->orWhere('ru.cognome', 'like', $like)
|
|
->orWhereRaw("TRIM(CONCAT(COALESCE(ru.nome, ''), ' ', COALESCE(ru.cognome, ''))) LIKE ?", [$like]);
|
|
})
|
|
->limit(1);
|
|
})
|
|
->orWhereExists(function ($sub) use ($like, $activeStabileId, $tenantRoles) {
|
|
$sub
|
|
->selectRaw('1')
|
|
->from('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $activeStabileId)
|
|
->where('rr.is_attivo', true)
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $tenantRoles)
|
|
->where(function ($w) use ($like) {
|
|
$w
|
|
->where('ru.ragione_sociale', 'like', $like)
|
|
->orWhere('ru.nome', 'like', $like)
|
|
->orWhere('ru.cognome', 'like', $like)
|
|
->orWhereRaw("TRIM(CONCAT(COALESCE(ru.nome, ''), ' ', COALESCE(ru.cognome, ''))) LIKE ?", [$like]);
|
|
})
|
|
->limit(1);
|
|
});
|
|
});
|
|
}
|
|
|
|
private function formatLegacyDenominazione(?string $titolo, ?string $denominazione): string
|
|
{
|
|
$titolo = trim((string) ($titolo ?? ''));
|
|
$den = trim((string) ($denominazione ?? ''));
|
|
|
|
if ($den === '') {
|
|
return '—';
|
|
}
|
|
|
|
if ($titolo === '') {
|
|
return $den;
|
|
}
|
|
|
|
// Caso tipico legacy: "ATER C" + "O UFFICIO ..." => "ATER C/O UFFICIO ..."
|
|
if (preg_match('/\bC\b/i', $titolo) && preg_match('/^O\b/i', $den)) {
|
|
return rtrim($titolo, '/') . '/' . ltrim($den, '/');
|
|
}
|
|
|
|
// Default: concat con spazio
|
|
return trim($titolo . ' ' . $den);
|
|
}
|
|
|
|
private function resolveUnitaIdForRow(mixed $record, int $activeStabileId): ?int
|
|
{
|
|
if ($record instanceof UnitaImmobiliare) {
|
|
return (int) $record->getKey();
|
|
}
|
|
|
|
$codStabileLegacy = trim((string) ($record->cod_stabile ?? ''));
|
|
$scala = trim((string) ($record->scala ?? ''));
|
|
$interno = trim((string) ($record->interno ?? ''));
|
|
|
|
if ($codStabileLegacy === '' || $interno === '') {
|
|
return null;
|
|
}
|
|
|
|
$codiceUnita = $codStabileLegacy . '-' . ($scala !== '' ? $scala : 'A') . '-' . $interno;
|
|
|
|
$id = UnitaImmobiliare::query()
|
|
->where('stabile_id', $activeStabileId)
|
|
->where('codice_unita', $codiceUnita)
|
|
->value('id');
|
|
|
|
return is_numeric($id) ? (int) $id : null;
|
|
}
|
|
|
|
private function resolveRubricaIdForRow(mixed $record): ?int
|
|
{
|
|
$cf = trim((string) ($record->cond_cod_fisc ?? $record->codice_fiscale ?? ''));
|
|
if ($cf !== '') {
|
|
$id = RubricaUniversale::query()
|
|
->where('codice_fiscale', strtoupper(preg_replace('/[^A-Z0-9]/i', '', $cf)))
|
|
->value('id');
|
|
if (is_numeric($id)) {
|
|
return (int) $id;
|
|
}
|
|
}
|
|
|
|
// Fallback best-effort su ragione sociale/nome completo (può essere costoso, quindi lo teniamo leggero)
|
|
$name = trim((string) ($record->nom_cond ?? ''));
|
|
if ($name === '') {
|
|
return null;
|
|
}
|
|
|
|
$id = RubricaUniversale::query()
|
|
->where('ragione_sociale', $name)
|
|
->orWhereRaw("TRIM(CONCAT(COALESCE(nome, ''), ' ', COALESCE(cognome, ''))) = ?", [$name])
|
|
->value('id');
|
|
|
|
return is_numeric($id) ? (int) $id : null;
|
|
}
|
|
|
|
private function resolveRubricaIdForInquilinoRow(mixed $record): ?int
|
|
{
|
|
$cf = trim((string) ($record->inquil_cod_fisc ?? ''));
|
|
if ($cf !== '') {
|
|
$id = RubricaUniversale::query()
|
|
->where('codice_fiscale', strtoupper(preg_replace('/[^A-Z0-9]/i', '', $cf)))
|
|
->value('id');
|
|
if (is_numeric($id)) {
|
|
return (int) $id;
|
|
}
|
|
}
|
|
|
|
$name = trim((string) ($record->inquil_nome ?? ''));
|
|
if ($name === '') {
|
|
return null;
|
|
}
|
|
|
|
$id = RubricaUniversale::query()
|
|
->where('ragione_sociale', $name)
|
|
->orWhereRaw("TRIM(CONCAT(COALESCE(nome, ''), ' ', COALESCE(cognome, ''))) = ?", [$name])
|
|
->value('id');
|
|
|
|
return is_numeric($id) ? (int) $id : null;
|
|
}
|
|
|
|
private function resolveRubricaTitoloById(?int $rubricaId): string
|
|
{
|
|
if (! $rubricaId) {
|
|
return '';
|
|
}
|
|
|
|
if (array_key_exists($rubricaId, $this->rubricaTitoloCache)) {
|
|
return $this->rubricaTitoloCache[$rubricaId];
|
|
}
|
|
|
|
$val = '';
|
|
if (DB::getSchemaBuilder()->hasTable('titoli') && DB::getSchemaBuilder()->hasColumn('rubrica_universale', 'titolo_id')) {
|
|
$val = (string) (DB::table('rubrica_universale as ru')
|
|
->leftJoin('titoli as t', 't.id', '=', 'ru.titolo_id')
|
|
->where('ru.id', $rubricaId)
|
|
->value(DB::raw("COALESCE(t.sigla, t.nome, '')")) ?: '');
|
|
}
|
|
|
|
return $this->rubricaTitoloCache[$rubricaId] = trim($val);
|
|
}
|
|
|
|
private function resolveTitoloOwnerForRow(mixed $record): string
|
|
{
|
|
$rubricaId = $this->resolveRubricaIdForRow($record);
|
|
$titolo = $this->resolveRubricaTitoloById($rubricaId);
|
|
if ($titolo !== '') {
|
|
return $titolo;
|
|
}
|
|
|
|
return trim((string) ($record->titolo_cond ?? ''));
|
|
}
|
|
|
|
private function resolveTitoloInquilinoForRow(mixed $record): string
|
|
{
|
|
$rubricaId = $this->resolveRubricaIdForInquilinoRow($record);
|
|
$titolo = $this->resolveRubricaTitoloById($rubricaId);
|
|
if ($titolo !== '') {
|
|
return $titolo;
|
|
}
|
|
|
|
return trim((string) ($record->titolo_inq ?? ''));
|
|
}
|
|
|
|
private function resolveCellulareForRow(mixed $record, bool $inquilino = false): string
|
|
{
|
|
$keys = $inquilino
|
|
? ['tenant_cellulare', 'cell_inq', 'inquil_cell', 'telefono_inq', 'cell_inquilino', 'telefono_cellulare_inq']
|
|
: ['owner_cellulare', 'cell_cond', 'cond_cell', 'telefono_cond', 'cell_condomino', 'telefono_cellulare_cond'];
|
|
|
|
foreach ($keys as $key) {
|
|
$val = trim((string) ($record->{$key} ?? ''));
|
|
if ($val !== '') {
|
|
return $val;
|
|
}
|
|
}
|
|
|
|
return '—';
|
|
}
|
|
|
|
private function resolveLegacyStabileCode(int $stabileId): string
|
|
{
|
|
$row = DB::table('stabili')
|
|
->where('id', $stabileId)
|
|
->first(['codice_stabile', 'cod_stabile']);
|
|
|
|
if (! $row) {
|
|
return '';
|
|
}
|
|
|
|
$legacy = trim((string) ($row->codice_stabile ?? ''));
|
|
if ($legacy !== '') {
|
|
return $legacy;
|
|
}
|
|
|
|
return trim((string) ($row->cod_stabile ?? ''));
|
|
}
|
|
|
|
protected static ?string $navigationLabel = 'Nominativi (condomini / inquilini)';
|
|
|
|
protected static ?string $title = 'Nominativi (condomini e inquilini)';
|
|
|
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-users';
|
|
|
|
protected static UnitEnum|string|null $navigationGroup = 'Stabile';
|
|
|
|
protected static ?int $navigationSort = 29;
|
|
|
|
protected static ?string $slug = 'condomini/nominativi';
|
|
|
|
protected string $view = 'filament.pages.condomini.nominativi-stabile';
|
|
|
|
public static function canAccess(): bool
|
|
{
|
|
$user = Auth::user();
|
|
return $user instanceof User
|
|
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
|
|
}
|
|
|
|
public function mount(): void
|
|
{
|
|
$user = Auth::user();
|
|
if ($user instanceof User) {
|
|
$requestedStabileId = request()->integer('stabile_id');
|
|
if ($requestedStabileId > 0) {
|
|
StabileContext::setActiveStabileId($user, $requestedStabileId);
|
|
}
|
|
|
|
$this->stabileId = StabileContext::resolveActiveStabileId($user);
|
|
|
|
if (! $this->stabileId) {
|
|
$fallbackStabileId = StabileContext::accessibleStabili($user)->first()?->id;
|
|
if ($fallbackStabileId) {
|
|
StabileContext::setActiveStabileId($user, (int) $fallbackStabileId);
|
|
$this->stabileId = (int) $fallbackStabileId;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->mountInteractsWithTable();
|
|
}
|
|
|
|
public function getStabiliOptions(): array
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return [];
|
|
}
|
|
|
|
return StabileContext::accessibleStabili($user)
|
|
->mapWithKeys(fn(Stabile $s) => [(int) $s->id => trim((string) ($s->codice_stabile . ' - ' . $s->denominazione))])
|
|
->all();
|
|
}
|
|
|
|
public function updatedStabileId($value): void
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return;
|
|
}
|
|
|
|
$id = is_numeric($value) ? (int) $value : 0;
|
|
if ($id <= 0) {
|
|
return;
|
|
}
|
|
|
|
if (! StabileContext::setActiveStabileId($user, $id)) {
|
|
return;
|
|
}
|
|
|
|
$this->stabileId = $id;
|
|
$this->resetPage();
|
|
$this->dispatch('$refresh');
|
|
}
|
|
|
|
protected function getTableQuery(): Builder
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
return LegacyCondominNominativo::query()->whereRaw('1 = 0');
|
|
}
|
|
|
|
$activeStabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $activeStabileId) {
|
|
return LegacyCondominNominativo::query()->whereRaw('1 = 0');
|
|
}
|
|
|
|
$codStabile = $this->resolveLegacyStabileCode((int) $activeStabileId);
|
|
if ($codStabile === '') {
|
|
return LegacyCondominNominativo::query()->whereRaw('1 = 0');
|
|
}
|
|
|
|
if (! $this->hasLegacyNominativiForStabile($codStabile)) {
|
|
return $this->buildDomainFallbackQuery((int) $activeStabileId);
|
|
}
|
|
|
|
$legacyTable = 'vw_legacy_condomin_nominativi';
|
|
|
|
$base = LegacyCondominNominativo::query()
|
|
->where($legacyTable . '.cod_stabile', $codStabile)
|
|
->where(function (Builder $q): void {
|
|
$q->whereRaw("TRIM(COALESCE(vw_legacy_condomin_nominativi.nom_cond, '')) <> ''")
|
|
->orWhereRaw("TRIM(COALESCE(vw_legacy_condomin_nominativi.inquil_nome, '')) <> ''");
|
|
});
|
|
|
|
$latestPerUnit = DB::connection('gescon_import')
|
|
->table('vw_legacy_condomin_nominativi')
|
|
->select('cod_stabile', 'scala', 'interno')
|
|
->selectRaw('MAX(legacy_year) as legacy_year')
|
|
->where('cod_stabile', $codStabile)
|
|
->groupBy('cod_stabile', 'scala', 'interno');
|
|
|
|
return $base
|
|
->joinSub($latestPerUnit, 'mx', function ($join): void {
|
|
$join->on('mx.cod_stabile', '=', 'vw_legacy_condomin_nominativi.cod_stabile')
|
|
->on('mx.scala', '=', 'vw_legacy_condomin_nominativi.scala')
|
|
->on('mx.interno', '=', 'vw_legacy_condomin_nominativi.interno')
|
|
->on('mx.legacy_year', '=', 'vw_legacy_condomin_nominativi.legacy_year');
|
|
})
|
|
->orderBy($legacyTable . '.scala')
|
|
// Ordine richiesto: per interno (con fallback robusto)
|
|
->orderByRaw("CASE WHEN vw_legacy_condomin_nominativi.interno IS NULL OR vw_legacy_condomin_nominativi.interno = '' THEN 1 ELSE 0 END")
|
|
->orderByRaw("CASE WHEN vw_legacy_condomin_nominativi.interno REGEXP '^[0-9]+' THEN CAST(vw_legacy_condomin_nominativi.interno AS UNSIGNED) ELSE 999999 END")
|
|
->orderBy($legacyTable . '.interno')
|
|
->orderBy($legacyTable . '.cod_cond')
|
|
->orderBy($legacyTable . '.id');
|
|
}
|
|
|
|
protected function hasLegacyNominativiForStabile(string $codStabile): bool
|
|
{
|
|
return DB::connection('gescon_import')
|
|
->table('condomin')
|
|
->where('cod_stabile', $codStabile)
|
|
->limit(1)
|
|
->exists();
|
|
}
|
|
|
|
protected function buildDomainFallbackQuery(int $stabileId): Builder
|
|
{
|
|
$today = now()->toDateString();
|
|
|
|
$ownerRoles = [
|
|
'condomino',
|
|
'proprietario',
|
|
'comproprietario',
|
|
'nudo_proprietario',
|
|
'usufruttuario',
|
|
'usufrutto',
|
|
];
|
|
$tenantRoles = [
|
|
'inquilino',
|
|
'locatario',
|
|
'conduttore',
|
|
];
|
|
|
|
$nameExpr = "CASE "
|
|
. "WHEN ru.tipo_contatto = 'persona_giuridica' AND COALESCE(ru.ragione_sociale, '') <> '' THEN ru.ragione_sociale ";
|
|
// Caso legacy frequente: denominazione azienda salvata come nome='O ...' e cognome='ATER C'
|
|
$nameExpr .= "WHEN TRIM(COALESCE(ru.nome, '')) LIKE 'O %' AND TRIM(COALESCE(ru.cognome, '')) LIKE '% C' THEN TRIM(CONCAT(COALESCE(ru.cognome, ''), '/', COALESCE(ru.nome, ''))) "
|
|
. "ELSE TRIM(CONCAT(COALESCE(ru.nome, ''), ' ', COALESCE(ru.cognome, ''))) END";
|
|
|
|
$phoneExpr = "COALESCE(NULLIF(TRIM(ru.telefono_cellulare), ''), NULLIF(TRIM(ru.telefono_ufficio), ''), NULLIF(TRIM(ru.telefono_casa), ''))";
|
|
|
|
$ownerNameSub = DB::table('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $stabileId)
|
|
->where('rr.is_attivo', true)
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_inizio')->orWhere('rr.data_inizio', '<=', $today);
|
|
})
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_fine')->orWhere('rr.data_fine', '>=', $today);
|
|
})
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $ownerRoles)
|
|
->orderByDesc('rr.is_preferito')
|
|
->orderByDesc('rr.data_inizio')
|
|
->orderByDesc('rr.id')
|
|
->selectRaw($nameExpr)
|
|
->limit(1);
|
|
|
|
$tenantNameSub = DB::table('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $stabileId)
|
|
->where('rr.is_attivo', true)
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_inizio')->orWhere('rr.data_inizio', '<=', $today);
|
|
})
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_fine')->orWhere('rr.data_fine', '>=', $today);
|
|
})
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $tenantRoles)
|
|
->orderByDesc('rr.is_preferito')
|
|
->orderByDesc('rr.data_inizio')
|
|
->orderByDesc('rr.id')
|
|
->selectRaw($nameExpr)
|
|
->limit(1);
|
|
|
|
$ownerPhoneSub = DB::table('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $stabileId)
|
|
->where('rr.is_attivo', true)
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_inizio')->orWhere('rr.data_inizio', '<=', $today);
|
|
})
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_fine')->orWhere('rr.data_fine', '>=', $today);
|
|
})
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $ownerRoles)
|
|
->orderByDesc('rr.is_preferito')
|
|
->orderByDesc('rr.data_inizio')
|
|
->orderByDesc('rr.id')
|
|
->selectRaw($phoneExpr)
|
|
->limit(1);
|
|
|
|
$tenantPhoneSub = DB::table('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $stabileId)
|
|
->where('rr.is_attivo', true)
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_inizio')->orWhere('rr.data_inizio', '<=', $today);
|
|
})
|
|
->where(function ($q) use ($today) {
|
|
$q->whereNull('rr.data_fine')->orWhere('rr.data_fine', '>=', $today);
|
|
})
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $tenantRoles)
|
|
->orderByDesc('rr.is_preferito')
|
|
->orderByDesc('rr.data_inizio')
|
|
->orderByDesc('rr.id')
|
|
->selectRaw($phoneExpr)
|
|
->limit(1);
|
|
|
|
return UnitaImmobiliare::query()
|
|
->where('stabile_id', $stabileId)
|
|
->whereNull('deleted_at')
|
|
->where(function (Builder $q) use ($stabileId, $ownerRoles, $tenantRoles): void {
|
|
$q->whereExists(function ($sub) use ($stabileId, $ownerRoles) {
|
|
$sub->selectRaw('1')
|
|
->from('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $stabileId)
|
|
->where('rr.is_attivo', true)
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $ownerRoles)
|
|
->where(function ($w) {
|
|
$w->whereRaw("TRIM(COALESCE(ru.ragione_sociale, '')) <> ''")
|
|
->orWhereRaw("TRIM(COALESCE(ru.nome, '')) <> ''")
|
|
->orWhereRaw("TRIM(COALESCE(ru.cognome, '')) <> ''");
|
|
})
|
|
->limit(1);
|
|
})->orWhereExists(function ($sub) use ($stabileId, $tenantRoles) {
|
|
$sub->selectRaw('1')
|
|
->from('rubrica_ruoli as rr')
|
|
->join('rubrica_universale as ru', 'ru.id', '=', 'rr.rubrica_id')
|
|
->whereColumn('rr.unita_immobiliare_id', 'unita_immobiliari.id')
|
|
->where('rr.stabile_id', $stabileId)
|
|
->where('rr.is_attivo', true)
|
|
->whereIn(DB::raw('LOWER(rr.ruolo_standard)'), $tenantRoles)
|
|
->where(function ($w) {
|
|
$w->whereRaw("TRIM(COALESCE(ru.ragione_sociale, '')) <> ''")
|
|
->orWhereRaw("TRIM(COALESCE(ru.nome, '')) <> ''")
|
|
->orWhereRaw("TRIM(COALESCE(ru.cognome, '')) <> ''");
|
|
})
|
|
->limit(1);
|
|
});
|
|
})
|
|
->select([
|
|
'unita_immobiliari.id',
|
|
'unita_immobiliari.scala',
|
|
'unita_immobiliari.piano',
|
|
'unita_immobiliari.interno',
|
|
])
|
|
->selectRaw('unita_immobiliari.codice_unita as cod_cond')
|
|
->selectSub($ownerNameSub, 'nom_cond')
|
|
->selectSub($tenantNameSub, 'inquil_nome')
|
|
->selectSub($ownerPhoneSub, 'owner_cellulare')
|
|
->selectSub($tenantPhoneSub, 'tenant_cellulare')
|
|
->selectRaw('NULL as perc_diritto_reale')
|
|
->orderBy('unita_immobiliari.scala')
|
|
->orderByRaw("CASE WHEN unita_immobiliari.interno IS NULL OR unita_immobiliari.interno = '' THEN 1 ELSE 0 END")
|
|
->orderByRaw("CASE WHEN unita_immobiliari.interno REGEXP '^[0-9]+' THEN CAST(unita_immobiliari.interno AS UNSIGNED) ELSE 999999 END")
|
|
->orderBy('unita_immobiliari.interno')
|
|
->orderBy('unita_immobiliari.id');
|
|
}
|
|
|
|
public function table(Table $table): Table
|
|
{
|
|
$user = Auth::user();
|
|
$activeStabileId = $user instanceof User ? (int) (StabileContext::resolveActiveStabileId($user) ?: 0): 0;
|
|
$legacyTable = 'vw_legacy_condomin_nominativi';
|
|
|
|
$codStabile = $activeStabileId > 0
|
|
? $this->resolveLegacyStabileCode((int) $activeStabileId)
|
|
: '';
|
|
|
|
$useLegacy = $codStabile !== '' && $this->hasLegacyNominativiForStabile($codStabile);
|
|
|
|
$legacyYear = $useLegacy
|
|
? (string) (DB::connection('gescon_import')->table('condomin')->where('cod_stabile', $codStabile)->max('legacy_year') ?: '')
|
|
: '';
|
|
|
|
return $table
|
|
->striped()
|
|
->filters([
|
|
SelectFilter::make('legacy_year')
|
|
->label('Anno legacy')
|
|
->visible(fn(): bool => (bool) $useLegacy)
|
|
->options(function () use ($codStabile): array {
|
|
if ($codStabile === '') {
|
|
return [];
|
|
}
|
|
return DB::connection('gescon_import')
|
|
->table('condomin')
|
|
->where('cod_stabile', $codStabile)
|
|
->whereNotNull('legacy_year')
|
|
->where('legacy_year', '<>', '')
|
|
->distinct()
|
|
->orderByDesc('legacy_year')
|
|
->pluck('legacy_year', 'legacy_year')
|
|
->all();
|
|
})
|
|
->query(function (Builder $query, array $data) use ($codStabile): Builder {
|
|
if (! isset($data['value']) || $data['value'] === '') {
|
|
return $query;
|
|
}
|
|
|
|
if (! $this->hasLegacyNominativiForStabile($codStabile)) {
|
|
return $query;
|
|
}
|
|
|
|
$table = $query->getModel()?->getTable();
|
|
if (! $table || ! DbSchema::hasColumn($table, 'legacy_year')) {
|
|
return $query;
|
|
}
|
|
|
|
return $query->where($table . '.legacy_year', $data['value']);
|
|
}),
|
|
SelectFilter::make('scala')
|
|
->label('Scala')
|
|
->options(function () use ($codStabile, $legacyYear, $activeStabileId): array {
|
|
if ($codStabile === '') {
|
|
return [];
|
|
}
|
|
|
|
if (! $this->hasLegacyNominativiForStabile($codStabile)) {
|
|
if ($activeStabileId <= 0) {
|
|
return [];
|
|
}
|
|
|
|
return UnitaImmobiliare::query()
|
|
->where('stabile_id', $activeStabileId)
|
|
->whereNull('deleted_at')
|
|
->whereNotNull('scala')
|
|
->where('scala', '<>', '')
|
|
->distinct()
|
|
->orderBy('scala')
|
|
->pluck('scala', 'scala')
|
|
->all();
|
|
}
|
|
|
|
return LegacyCondominNominativo::query()
|
|
->where('cod_stabile', $codStabile)
|
|
->when($legacyYear !== '', fn(Builder $q) => $q->where('legacy_year', $legacyYear))
|
|
->whereNotNull('scala')
|
|
->where('scala', '<>', '')
|
|
->distinct()
|
|
->orderBy('scala')
|
|
->pluck('scala', 'scala')
|
|
->all();
|
|
})
|
|
->query(function (Builder $query, array $data) use ($legacyTable): Builder {
|
|
if (! isset($data['value']) || $data['value'] === '') {
|
|
return $query;
|
|
}
|
|
|
|
$model = $query->getModel();
|
|
if ($model instanceof LegacyCondominNominativo) {
|
|
return $query->where($legacyTable . '.scala', $data['value']);
|
|
}
|
|
|
|
return $query->where('scala', $data['value']);
|
|
})
|
|
->searchable(),
|
|
|
|
SelectFilter::make('piano')
|
|
->label('Piano')
|
|
->options(function () use ($codStabile, $legacyYear, $activeStabileId): array {
|
|
if ($codStabile === '') {
|
|
return [];
|
|
}
|
|
|
|
if (! $this->hasLegacyNominativiForStabile($codStabile)) {
|
|
if ($activeStabileId <= 0) {
|
|
return [];
|
|
}
|
|
|
|
return UnitaImmobiliare::query()
|
|
->where('stabile_id', $activeStabileId)
|
|
->whereNull('deleted_at')
|
|
->whereNotNull('piano')
|
|
->where('piano', '<>', '')
|
|
->distinct()
|
|
->orderBy('piano')
|
|
->pluck('piano', 'piano')
|
|
->all();
|
|
}
|
|
|
|
return LegacyCondominNominativo::query()
|
|
->where('cod_stabile', $codStabile)
|
|
->when($legacyYear !== '', fn(Builder $q) => $q->where('legacy_year', $legacyYear))
|
|
->whereNotNull('piano')
|
|
->where('piano', '<>', '')
|
|
->distinct()
|
|
->orderBy('piano')
|
|
->pluck('piano', 'piano')
|
|
->all();
|
|
})
|
|
->searchable(),
|
|
|
|
TernaryFilter::make('ha_inquilino')
|
|
->label('Inquilino')
|
|
->trueLabel('Con inquilino')
|
|
->falseLabel('Senza inquilino')
|
|
->queries(
|
|
true: fn(Builder $query) => $query->whereNotNull('inquil_nome')->where('inquil_nome', '<>', ''),
|
|
false: fn(Builder $query) => $query->where(function (Builder $q) {
|
|
$q->whereNull('inquil_nome')->orWhere('inquil_nome', '');
|
|
}),
|
|
),
|
|
])
|
|
->columns([
|
|
TextColumn::make('unita_ref')
|
|
->label('Unità')
|
|
->formatStateUsing(function ($state, $record): string {
|
|
$scala = trim((string) ($record->scala ?? ''));
|
|
$interno = trim((string) ($record->interno ?? ''));
|
|
$piano = trim((string) ($record->piano ?? ''));
|
|
|
|
$parts = [];
|
|
if ($scala !== '') {
|
|
$parts[] = 'Sc. ' . $scala;
|
|
}
|
|
if ($interno !== '') {
|
|
$parts[] = 'Int. ' . $interno;
|
|
}
|
|
if ($piano !== '') {
|
|
$parts[] = 'P. ' . $piano;
|
|
}
|
|
|
|
return $parts === [] ? '—' : implode(' · ', $parts);
|
|
})
|
|
->wrap(),
|
|
|
|
TextColumn::make('scala')
|
|
->label('Sc.')
|
|
->sortable(query: function (Builder $query, string $direction) use ($legacyTable): Builder {
|
|
$model = $query->getModel();
|
|
if ($model instanceof LegacyCondominNominativo) {
|
|
return $query->orderBy($legacyTable . '.scala', $direction);
|
|
}
|
|
|
|
return $query->orderBy('scala', $direction);
|
|
}),
|
|
|
|
TextColumn::make('interno')
|
|
->label('Int.')
|
|
->sortable(query: function (Builder $query, string $direction) use ($legacyTable): Builder {
|
|
$model = $query->getModel();
|
|
if ($model instanceof LegacyCondominNominativo) {
|
|
return $query->orderBy($legacyTable . '.interno', $direction);
|
|
}
|
|
|
|
return $query->orderBy('interno', $direction);
|
|
})
|
|
->searchable(query: function (Builder $query, string $search) use ($activeStabileId, $legacyTable): Builder {
|
|
$model = $query->getModel();
|
|
if ($model instanceof LegacyCondominNominativo) {
|
|
return $query->where($legacyTable . '.interno', 'like', '%' . $search . '%');
|
|
}
|
|
|
|
return $this->applyDomainNominativiSearch($query, $search, $activeStabileId);
|
|
}),
|
|
|
|
TextColumn::make('nom_cond')
|
|
->label('Condomino')
|
|
->formatStateUsing(function ($state, $record): string {
|
|
$titolo = $this->resolveTitoloOwnerForRow($record);
|
|
return $this->formatLegacyDenominazione($titolo, $record->nom_cond ?? (string) $state);
|
|
})
|
|
->searchable(query: function (Builder $query, string $search) use ($activeStabileId, $legacyTable): Builder {
|
|
$model = $query->getModel();
|
|
if ($model instanceof LegacyCondominNominativo) {
|
|
return $query->where($legacyTable . '.nom_cond', 'like', '%' . $search . '%');
|
|
}
|
|
|
|
return $this->applyDomainNominativiSearch($query, $search, $activeStabileId);
|
|
})
|
|
->wrap(),
|
|
|
|
TextColumn::make('periodo')
|
|
->label('Periodo')
|
|
->formatStateUsing(function ($state, $record): string {
|
|
$da = $record->data_inizio ?? null;
|
|
$a = $record->data_fine ?? null;
|
|
|
|
$format = static function ($value): ?string {
|
|
if (empty($value)) {
|
|
return null;
|
|
}
|
|
try {
|
|
return \Carbon\Carbon::parse($value)->format('d/m/Y');
|
|
} catch (\Throwable $e) {
|
|
return (string) $value;
|
|
}
|
|
};
|
|
|
|
$daLabel = $format($da);
|
|
$aLabel = $format($a);
|
|
|
|
if (! $daLabel && ! $aLabel) {
|
|
return '—';
|
|
}
|
|
|
|
$parts = [];
|
|
if ($daLabel) {
|
|
$parts[] = 'Da ' . $daLabel;
|
|
}
|
|
if ($aLabel) {
|
|
$parts[] = 'fino a ' . $aLabel;
|
|
}
|
|
|
|
return '(' . implode(' · ', $parts) . ')';
|
|
})
|
|
->wrap(),
|
|
|
|
TextColumn::make('inquil_nome')
|
|
->label('Inquilino')
|
|
->formatStateUsing(function ($state, $record): string {
|
|
$v = trim((string) ($state ?? ''));
|
|
if ($v === '') {
|
|
return '—';
|
|
}
|
|
$titolo = $this->resolveTitoloInquilinoForRow($record);
|
|
return $this->formatLegacyDenominazione($titolo, $v);
|
|
})
|
|
->searchable(query: function (Builder $query, string $search) use ($activeStabileId, $legacyTable): Builder {
|
|
$model = $query->getModel();
|
|
if ($model instanceof LegacyCondominNominativo) {
|
|
return $query->where($legacyTable . '.inquil_nome', 'like', '%' . $search . '%');
|
|
}
|
|
|
|
return $this->applyDomainNominativiSearch($query, $search, $activeStabileId);
|
|
})
|
|
->wrap(),
|
|
|
|
TextColumn::make('cell_cond')
|
|
->label('Cell. Cond.')
|
|
->formatStateUsing(fn($state, $record): string => $this->resolveCellulareForRow($record, false))
|
|
->wrap(),
|
|
|
|
TextColumn::make('cell_inq')
|
|
->label('Cell. Inq.')
|
|
->formatStateUsing(fn($state, $record): string => $this->resolveCellulareForRow($record, true))
|
|
->wrap(),
|
|
|
|
TextColumn::make('titolo_cond')
|
|
->label('Tit. Cond.')
|
|
->formatStateUsing(fn($state, $record): string => $this->resolveTitoloOwnerForRow($record) ?: '—')
|
|
->toggleable(isToggledHiddenByDefault: true),
|
|
|
|
TextColumn::make('titolo_inq')
|
|
->label('Tit. Inq.')
|
|
->formatStateUsing(fn($state, $record): string => $this->resolveTitoloInquilinoForRow($record) ?: '—')
|
|
->toggleable(isToggledHiddenByDefault: true),
|
|
])
|
|
->actions([
|
|
Action::make('apri_unita')
|
|
->label('Unità')
|
|
->icon('heroicon-o-home')
|
|
->url(function ($record) use ($activeStabileId): ?string {
|
|
if ($activeStabileId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$unitaId = $this->resolveUnitaIdForRow($record, $activeStabileId);
|
|
if (! $unitaId) {
|
|
return null;
|
|
}
|
|
|
|
return UnitaImmobiliarePage::getUrl(panel: 'admin-filament') . '?unita_id=' . $unitaId;
|
|
}, shouldOpenInNewTab: true)
|
|
->visible(fn($record): bool => (bool) $this->resolveUnitaIdForRow($record, $activeStabileId)),
|
|
|
|
Action::make('apri_scheda_unica')
|
|
->label('Scheda unica')
|
|
->icon('heroicon-o-identification')
|
|
->url(function ($record): ?string {
|
|
$rubricaId = $this->resolveRubricaIdForRow($record);
|
|
if (! $rubricaId) {
|
|
return null;
|
|
}
|
|
|
|
return RubricaUniversaleScheda::getUrl(['record' => $rubricaId], panel: 'admin-filament');
|
|
}, shouldOpenInNewTab: true)
|
|
->visible(fn($record): bool => (bool) $this->resolveRubricaIdForRow($record)),
|
|
]);
|
|
}
|
|
}
|