netgescon-day0/app/Services/GesconImport/Steps/HandlesSoggettiStep.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;
}
}