hasTable('condomin')) { return 0; } $stabileId = $this->resolveStabileId(); $count = 0; $updated = 0; // Se nel mapping sono presenti codici cassa target (es. CCB, CDL), assicurali nelle casse try { if (!empty($this->banksMapping) && Schema::hasTable('casse') && $stabileId) { foreach ($this->banksMapping as $bm) { if (!is_array($bm)) { continue; } $code = $this->resolveMappingCodiceCassa($bm); if ($code) { $exists = DB::table('casse')->where('stabile_id', $stabileId)->where('cod_cassa', $code)->first(); if (!$exists) { DB::table('casse')->insert([ 'tenant_id' => null, 'stabile_id' => $stabileId, 'cod_cassa' => $code, 'descrizione' => 'Cassa ' . $code, 'tipo' => ($code === 'CON') ? 'cassa_contanti' : (($code === 'CDL') ? 'altro' : 'conto_bancario_locale'), 'iban' => null, 'intestazione_conto' => null, 'attiva' => true, 'meta' => json_encode(['from_mapping' => true]), 'created_at' => now(), 'updated_at' => now(), ]); } } } } } catch (\Throwable $e) { } $processed = 0; $batch = $limit ? min(max(1, $limit), 1000) : 1000; $offset = 0; while (true) { $q = DB::connection('gescon_import')->table('condomin'); if ($this->option('stabile')) { $q->where('cod_stabile', $this->option('stabile')); } if ($this->option('scala')) { $q->where('scala', $this->option('scala')); } $q->limit($batch)->offset($offset); $rows = $q->get(); if ($rows->isEmpty()) { break; } foreach ($rows as $r) { $cf = trim((string)($r->codice_fiscale ?? '')) ?: null; if ($cf) { $cf = strtoupper($cf); } $email = trim((string)($r->email ?? '')) ?: null; $nome = isset($r->nome) ? trim((string)$r->nome) : null; $cognome = isset($r->cognome) ? trim((string)$r->cognome) : null; if ($nome === '') { $nome = null; } if ($cognome === '') { $cognome = null; } if (!$nome && !$cognome) { continue; } // Unique/dedup: preferisci CF -> email -> nome+cognome normalizzati (no uso old_id per evitare duplicati per UI) $useDbTrigger = (bool)env('GESCON_USE_DB_TRIGGER_CODES', false); $exists = $this->findExistingSoggetto($cf, $email, $nome, $cognome); if ($exists) { // Upsert non distruttivo: completa campi mancanti $patch = []; foreach ([ 'nome' => $nome, 'cognome' => $cognome, 'codice_fiscale' => $cf, 'email' => $email, 'telefono' => $r->telefono ?? null, 'indirizzo' => $r->indirizzo_corrispondenza ?? null, ] as $k => $v) { if (!empty($v) && (empty($exists->$k) || $exists->$k === 'ND')) { $patch[$k] = $v; } } if (!empty($patch)) { $patch['updated_at'] = now(); DB::table('soggetti')->where('id', $exists->id)->update($patch); $updated++; } $fresh = DB::table('soggetti')->where('id', $exists->id)->first(); $this->ensurePersonaForSoggetto($fresh ?? $exists); continue; } // Tipo soggetto derivato da flag proprietario/inquilino $tipo = null; if (property_exists($r, 'inquilino') && $r->inquilino) { $tipo = 'inquilino'; } elseif (property_exists($r, 'proprietario') && $r->proprietario) { $tipo = 'proprietario'; } $data = [ 'old_id' => $this->safeOldId($r->cod_cond ?? null), 'nome' => $nome, 'cognome' => $cognome, 'ragione_sociale' => null, 'codice_fiscale' => $cf, 'partita_iva' => null, 'email' => $email, 'telefono' => $r->telefono ?? null, 'indirizzo' => $r->indirizzo_corrispondenza ?? null, 'cap' => null, 'citta' => null, 'provincia' => null, 'tipo' => $tipo ?? 'proprietario', 'attivo' => Schema::hasColumn('soggetti', 'attivo') ? true : null, 'created_at' => now(), 'updated_at' => now() ]; if (!$useDbTrigger) { $baseKey = $this->normalizeNameKey($nome, $cognome) ?: ($email ?: 'ND'); $this->dedupSoggettiByNameKey(); $code = $this->generateStableCondKey('S', $r->cod_stabile ?? 'S0', $baseKey); // Ensure uniqueness by retrying with cond code salt $tries = 0; while (Schema::hasTable('soggetti') && DB::table('soggetti')->where('codice_univoco', $code)->exists() && $tries < 3) { $salt = ($r->cod_cond ?? '') . '-' . ($tries + 1); $code = $this->generateStableCondKey('S', $r->cod_stabile ?? 'S0', $baseKey . '|' . $salt); $tries++; } $data['codice_univoco'] = $code; } // Final guard: skip if same unique code already exists with same name/email if (Schema::hasTable('soggetti') && isset($data['codice_univoco'])) { $ex = DB::table('soggetti')->where('codice_univoco', $data['codice_univoco'])->first(); if ($ex) { continue; } } $this->dynamicInsert('soggetti', $data); $count++; $processed++; $inserted = $this->findExistingSoggetto($cf, $email, $nome, $cognome); if (!$inserted && isset($data['codice_univoco'])) { $inserted = DB::table('soggetti')->where('codice_univoco', $data['codice_univoco'])->first(); } $this->ensurePersonaForSoggetto($inserted); if ($limit && $processed >= $limit) { break 2; } } $offset += $batch; } // Dedup dopo inserimento: unisci per CF e per email $this->dedupSoggettiBy('codice_fiscale'); $this->dedupSoggettiBy('email'); return $count + $updated; } }