174 lines
7.8 KiB
PHP
174 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\GesconImport\Steps;
|
|
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
trait HandlesSoggettiStep
|
|
{
|
|
private function stepSoggetti(?int $limit): int
|
|
{
|
|
// Deriva da proprietari/inquilini nei campi condomin
|
|
if (!Schema::connection('gescon_import')->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;
|
|
}
|
|
}
|