netgescon-day0/app/Console/Commands/GesconQaRubricaVuotiCommand.php

162 lines
6.0 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class GesconQaRubricaVuotiCommand extends Command
{
protected $signature = 'gescon:qa-rubrica-vuoti
{--id=* : ID rubrica specifici da analizzare}
{--stabile= : Codice stabile legacy}
{--limit=200 : Limite record}
{--apply : Applica solo riempimenti sicuri da legacy}';
protected $description = 'Analizza contatti rubrica condomino senza identita e propone/riempie dati da gescon_import.condomin.';
public function handle(): int
{
if (! Schema::hasTable('rubrica_universale') || ! Schema::connection('gescon_import')->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 !== '');
}
}