hasTable('condomin')) { $this->error('Tabelle richieste mancanti.'); return self::FAILURE; } $ids = array_values(array_filter(array_map( fn($value): int => is_numeric($value) ? (int) $value : 0, (array) $this->option('id') ))); $query = DB::table('rubrica_universale') ->where('categoria', 'condomino') ->where(function ($builder): void { $builder->whereNull('nome')->orWhere('nome', '')->orWhere('nome', '?'); }) ->where(function ($builder): void { $builder->whereNull('cognome')->orWhere('cognome', ''); }) ->where(function ($builder): void { $builder->whereNull('ragione_sociale')->orWhere('ragione_sociale', ''); }); if ($ids !== []) { $query->whereIn('id', $ids); } $stabileFilter = trim((string) ($this->option('stabile') ?? '')); if ($stabileFilter !== '') { $query->where('note', 'like', '%cod_stabile=' . $stabileFilter . '%'); } $rows = $query ->orderBy('id') ->limit(max(1, min(5000, (int) $this->option('limit')))) ->get(); $apply = (bool) $this->option('apply'); $fixed = 0; $unresolved = 0; foreach ($rows as $row) { $legacy = $this->parseLegacyNote((string) ($row->note ?? '')); $match = $this->findLegacyRow($legacy); if (! $match) { $unresolved++; $this->warn('#' . $row->id . ' ' . $row->codice_univoco . ' nessun match legacy'); continue; } $payload = $this->buildPayload($match, (string) ($legacy['ruolo'] ?? 'condomino')); if ($payload === []) { $unresolved++; $this->warn('#' . $row->id . ' ' . $row->codice_univoco . ' match senza identita utile'); continue; } $this->line('#' . $row->id . ' ' . $row->codice_univoco . ' -> ' . json_encode($payload, JSON_UNESCAPED_UNICODE)); if ($apply) { $payload['updated_at'] = now(); if (Schema::hasColumn('rubrica_universale', 'data_ultima_modifica')) { $payload['data_ultima_modifica'] = now()->toDateString(); } DB::table('rubrica_universale')->where('id', $row->id)->update($payload); } $fixed++; } $this->info('Analizzati: ' . $rows->count() . ' | risolvibili: ' . $fixed . ' | non risolti: ' . $unresolved . ($apply ? ' | applicato' : ' | dry-run')); return self::SUCCESS; } private function parseLegacyNote(string $note): array { $out = ['cod_stabile' => null, 'cod_cond' => null, 'ruolo' => null]; foreach ($out as $key => $_) { if (preg_match('/' . preg_quote($key, '/') . '=([^|]+)/', $note, $matches)) { $out[$key] = trim($matches[1]); } } return $out; } private function findLegacyRow(array $legacy): ?object { $codStabile = trim((string) ($legacy['cod_stabile'] ?? '')); $codCond = trim((string) ($legacy['cod_cond'] ?? '')); if ($codStabile === '' || $codCond === '') { return null; } return DB::connection('gescon_import') ->table('condomin') ->where('cod_stabile', $codStabile) ->where(function ($builder) use ($codCond): void { $builder->where('cod_cond', $codCond) ->orWhere('id_cond', $codCond) ->orWhere('legacy_id_cond', $codCond); }) ->orderByDesc('legacy_year') ->orderByDesc('id') ->first(); } private function buildPayload(object $row, string $ruolo): array { $role = mb_strtolower(trim($ruolo)); $name = $role === 'inquilino' ? trim((string) ($row->inquilino_denominazione ?? $row->inquil_nome ?? '')) : trim((string) ($row->nom_cond ?? $row->proprietario_denominazione ?? '')); if ($name === '' || $name === '?') { return []; } $parts = preg_split('/\s+/', $name) ?: []; $payload = [ 'ragione_sociale' => $name, 'nome' => null, 'cognome' => null, 'codice_fiscale' => $role === 'inquilino' ? (trim((string) ($row->inquil_cod_fisc ?? '')) ?: null) : (trim((string) ($row->cond_cod_fisc ?? '')) ?: null), 'email' => $role === 'inquilino' ? (trim((string) ($row->e_mail_inquilino ?? '')) ?: null) : (trim((string) ($row->e_mail_condomino ?? '')) ?: null), 'telefono_cellulare' => $role === 'inquilino' ? (trim((string) ($row->cell_inq ?? '')) ?: null) : (trim((string) ($row->cell_cond ?? '')) ?: null), ]; if (count($parts) >= 2 && ! str_contains($name, '-') && ! str_contains($name, '&')) { $payload['cognome'] = array_shift($parts); $payload['nome'] = implode(' ', $parts); } return array_filter($payload, fn($value) => $value !== null && $value !== ''); } }