288 lines
12 KiB
PHP
Executable File
288 lines
12 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
class MapGesconStabiliCommand extends Command
|
|
{
|
|
protected $signature = 'gescon:import-stabili
|
|
{--mdb=/home/michele/netgescon/docs/02-architettura-laravel/Gescon/dbc/Stabili.mdb : Percorso file Stabili.mdb}
|
|
{--linux-base=/home/michele/netgescon/docs/02-architettura-laravel/Gescon/ : Base path Linux per cartelle stabile}
|
|
{--win-base= : Base path Windows}
|
|
{--amministratore-id= : Forza l\'assegnazione dello stabile a questo amministratore}
|
|
{--dry-run : Simula senza scrivere}';
|
|
|
|
protected $description = 'Importa/aggiorna stabili da Stabili.mdb in tabella dominio e salva riferimenti Gescon in configurazione_avanzata';
|
|
|
|
public function handle(): int
|
|
{
|
|
$mdb = $this->option('mdb');
|
|
$linuxBase = rtrim((string)($this->option('linux-base') ?? ''), '/') . '/';
|
|
$winBase = $this->option('win-base');
|
|
$dry = (bool)$this->option('dry-run');
|
|
$amminId = $this->option('amministratore-id') ? (int)$this->option('amministratore-id') : null;
|
|
if (!is_file($mdb)) {
|
|
$this->error("File MDB non trovato: $mdb");
|
|
return 1;
|
|
}
|
|
if (!Schema::hasTable('stabili')) {
|
|
$this->error('Tabella stabili non presente.');
|
|
return 1;
|
|
}
|
|
|
|
$rows = $this->exportMdbTable($mdb, 'Stabili');
|
|
if (empty($rows)) {
|
|
$this->warn('Nessuna riga letta da Stabili.mdb');
|
|
return 0;
|
|
}
|
|
|
|
$created = 0;
|
|
$updated = 0;
|
|
$skipped = 0;
|
|
foreach ($rows as $row) {
|
|
$r = $this->normalizeKeys($row);
|
|
$nomeDir = trim($r['nome_directory'] ?? '');
|
|
$codStab = trim((string)($r['cod_stabile'] ?? ''));
|
|
if ($nomeDir === '' && $codStab === '') {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
$colCode = Schema::hasColumn('stabili', 'codice_stabile') ? 'codice_stabile' : (Schema::hasColumn('stabili', 'denominazione') ? 'denominazione' : null);
|
|
if (!$colCode) {
|
|
$this->error('Colonna codice/denominazione non disponibile in stabili.');
|
|
return 1;
|
|
}
|
|
|
|
$exists = DB::table('stabili')->where($colCode, $nomeDir ?: $codStab)->first();
|
|
if (!$exists && !empty($codStab) && Schema::hasColumn('stabili', 'old_id')) {
|
|
$exists = DB::table('stabili')->where('old_id', $codStab)->first();
|
|
}
|
|
|
|
$cfStabile = trim((string)($r['codice_fisc'] ?? $r['cf_condominio'] ?? $r['codice_fiscale'] ?? $r['codice_fiscale_cond'] ?? ''));
|
|
$ibanBanca = trim((string)($r['iban_principale'] ?? $r['iban_banca'] ?? $r['iban'] ?? ''));
|
|
$bancaDenom = trim((string)($r['denominazione_banca'] ?? $r['banca'] ?? ''));
|
|
|
|
$data = [
|
|
$colCode => $nomeDir ?: $codStab,
|
|
'denominazione' => $r['denominazione'] ?? ($r['fe_denominazione'] ?? ($nomeDir ?: $codStab)),
|
|
'indirizzo' => $r['indirizzo'] ?? ($r['indir_autorizzazione'] ?? ($r['indir_autorizzazione_2'] ?? 'ND')),
|
|
'cap' => $this->sanitizeCap($r['cap'] ?? null) ?: '00000',
|
|
'citta' => $this->sanitizeCitta($r['citta'] ?? null) ?: 'ND',
|
|
'provincia' => $this->sanitizeProvincia($r['pr'] ?? null) ?: 'XX',
|
|
'codice_destinatario_sdi' => $r['fe_codice_destinatario'] ?? null,
|
|
'pec_condominio' => $r['fe_pec'] ?? null,
|
|
'codice_fiscale' => $cfStabile !== '' ? $cfStabile : null,
|
|
'iban_principale' => $ibanBanca !== '' ? $ibanBanca : null,
|
|
'banca_principale' => $bancaDenom !== '' ? $bancaDenom : null,
|
|
'updated_at' => now(),
|
|
];
|
|
if ($amminId && Schema::hasColumn('stabili', 'amministratore_id')) {
|
|
$data['amministratore_id'] = $amminId;
|
|
}
|
|
$configExtra = [
|
|
'gescon' => [
|
|
'cod_stabile' => $codStab ?: null,
|
|
'nome_directory' => $nomeDir ?: null,
|
|
'path_linux' => $linuxBase && $nomeDir ? ($linuxBase . $nomeDir . '/') : null,
|
|
'path_windows' => $winBase && $nomeDir ? ($winBase . '\\' . $nomeDir . '\\') : null,
|
|
],
|
|
'ac_catasto' => $this->collectPrefix($r, 'ac_'),
|
|
'fe' => $this->collectPrefix($r, 'fe_'),
|
|
'rata_flags' => [
|
|
'ord' => $this->collectPrefix($r, 'ord_rata_'),
|
|
'ris' => $this->collectPrefix($r, 'ris_rata_'),
|
|
],
|
|
'770' => $this->collectPrefix($r, 'amm_770_'),
|
|
'banca' => [
|
|
'abi' => $r['abi'] ?? null,
|
|
'cab' => $r['cab'] ?? null,
|
|
'sia' => $r['sia'] ?? null,
|
|
'iban_banca' => $r['iban_banca'] ?? null,
|
|
'iban_posta' => $r['iban_posta'] ?? null,
|
|
'banca' => $r['banca'] ?? null,
|
|
'banca2' => $r['banca2'] ?? null,
|
|
'num_ccp' => $r['num_ccp'] ?? null,
|
|
'intestaz_ccp' => $r['intestaz_ccp'] ?? null,
|
|
],
|
|
];
|
|
|
|
if ($exists) {
|
|
if (!$dry) {
|
|
// Safe assign old_id only if free or same row
|
|
if (!empty($codStab) && Schema::hasColumn('stabili', 'old_id')) {
|
|
$holder = DB::table('stabili')->where('old_id', $codStab)->first();
|
|
if (!$holder || $holder->id == $exists->id) {
|
|
$data['old_id'] = $codStab;
|
|
}
|
|
}
|
|
$merged = $this->mergeConfigJson($exists->configurazione_avanzata ?? null, $configExtra);
|
|
$data['configurazione_avanzata'] = $merged;
|
|
$this->safeUpdate('stabili', ['id' => $exists->id], $data);
|
|
}
|
|
$updated++;
|
|
} else {
|
|
if (!$dry) {
|
|
// Ensure amministratore_id if column is NOT nullable
|
|
if (Schema::hasColumn('stabili', 'amministratore_id') && !$amminId) {
|
|
$ammin = DB::table('amministratori')->first();
|
|
if (!$ammin) {
|
|
// Create minimal user+amministratore seed
|
|
$user = DB::table('users')->first();
|
|
if (!$user) {
|
|
$userId = DB::table('users')->insertGetId([
|
|
'name' => 'Admin Seed',
|
|
'email' => 'admin-seed@example.local',
|
|
'password' => bcrypt('password'),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
} else {
|
|
$userId = $user->id;
|
|
}
|
|
$amminId = DB::table('amministratori')->insertGetId([
|
|
'nome' => 'Admin',
|
|
'cognome' => 'Seed',
|
|
'user_id' => $userId,
|
|
'codice_univoco' => 'ASEED001',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
} else {
|
|
$amminId = $ammin->id;
|
|
}
|
|
}
|
|
if (Schema::hasColumn('stabili', 'amministratore_id')) {
|
|
$data['amministratore_id'] = $amminId;
|
|
}
|
|
$data['attivo'] = true;
|
|
$data['created_at'] = now();
|
|
$data['configurazione_avanzata'] = json_encode($configExtra);
|
|
// Safe set old_id only if not taken
|
|
if (!empty($codStab) && Schema::hasColumn('stabili', 'old_id')) {
|
|
$existsOld = DB::table('stabili')->where('old_id', $codStab)->exists();
|
|
if (!$existsOld) {
|
|
$data['old_id'] = $codStab;
|
|
}
|
|
}
|
|
$this->safeInsert('stabili', $data);
|
|
}
|
|
$created++;
|
|
}
|
|
}
|
|
|
|
$this->info("Stabili importati. Creati: $created, Aggiornati: $updated, Ignorati: $skipped");
|
|
return 0;
|
|
}
|
|
|
|
private function exportMdbTable(string $mdbPath, string $table): array
|
|
{
|
|
// Use a temp file to let fgetcsv handle embedded newlines safely
|
|
$tmp = tempnam(sys_get_temp_dir(), 'mdbcsv_');
|
|
$cmd = sprintf(
|
|
'mdb-export -D %s -d %s -q %s -R "\\n" %s %s > %s 2>/dev/null',
|
|
escapeshellarg('%Y-%m-%d'),
|
|
escapeshellarg('|'),
|
|
escapeshellarg('"'),
|
|
escapeshellarg($mdbPath),
|
|
escapeshellarg($table),
|
|
escapeshellarg($tmp)
|
|
);
|
|
shell_exec($cmd);
|
|
if (!is_file($tmp) || filesize($tmp) === 0) {
|
|
@unlink($tmp);
|
|
return [];
|
|
}
|
|
$fh = fopen($tmp, 'r');
|
|
if (!$fh) {
|
|
@unlink($tmp);
|
|
return [];
|
|
}
|
|
$headers = fgetcsv($fh, 0, '|');
|
|
if (!$headers) {
|
|
fclose($fh);
|
|
@unlink($tmp);
|
|
return [];
|
|
}
|
|
$headers = array_map(fn($h) => strtolower(trim($h)), $headers);
|
|
$rows = [];
|
|
while (($cols = fgetcsv($fh, 0, '|')) !== false) {
|
|
if (count($cols) !== count($headers)) {
|
|
// pad/truncate to match headers length
|
|
$cols = array_pad($cols, count($headers), null);
|
|
$cols = array_slice($cols, 0, count($headers));
|
|
}
|
|
$rows[] = array_combine($headers, $cols);
|
|
}
|
|
fclose($fh);
|
|
@unlink($tmp);
|
|
return $rows;
|
|
}
|
|
|
|
private function normalizeKeys(array $row): array
|
|
{
|
|
$norm = [];
|
|
foreach ($row as $k => $v) {
|
|
$norm[strtolower($k)] = $v;
|
|
}
|
|
return $norm;
|
|
}
|
|
|
|
private function collectPrefix(array $r, string $prefix): array
|
|
{
|
|
$out = [];
|
|
foreach ($r as $k => $v) {
|
|
if (str_starts_with($k, $prefix)) $out[$k] = $v;
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
private function mergeConfigJson(?string $existingJson, array $extra): string
|
|
{
|
|
$existing = $existingJson ? (json_decode($existingJson, true) ?: []) : [];
|
|
return json_encode(array_replace_recursive($existing, $extra));
|
|
}
|
|
|
|
private function safeInsert(string $table, array $data): void
|
|
{
|
|
$cols = Schema::getColumnListing($table);
|
|
DB::table($table)->insert(array_intersect_key($data, array_flip($cols)));
|
|
}
|
|
|
|
private function safeUpdate(string $table, array $where, array $data): void
|
|
{
|
|
$cols = Schema::getColumnListing($table);
|
|
DB::table($table)->where($where)->update(array_intersect_key($data, array_flip($cols)));
|
|
}
|
|
|
|
private function sanitizeCap($v): ?string
|
|
{
|
|
if ($v === null || $v === '') return null;
|
|
$s = preg_replace('/[^0-9]/', '', (string)$v);
|
|
if ($s === '') return null;
|
|
return substr($s, 0, 5);
|
|
}
|
|
|
|
private function sanitizeProvincia($v): ?string
|
|
{
|
|
if ($v === null || $v === '') return null;
|
|
$s = strtoupper(preg_replace('/[^A-Z]/', '', (string)$v));
|
|
if ($s === '') return null;
|
|
return substr($s, 0, 2);
|
|
}
|
|
|
|
private function sanitizeCitta($v): ?string
|
|
{
|
|
if ($v === null || $v === '') return null;
|
|
$s = trim((string)$v);
|
|
// Rimuovi spazi interni anomali tipo 'R O M A'
|
|
if (preg_match('/^(?:[A-Z]\s+)+[A-Z]$/', strtoupper($s))) {
|
|
$s = preg_replace('/\s+/', '', $s);
|
|
}
|
|
return substr($s, 0, 100);
|
|
}
|
|
}
|