option('stabile-id') ?? 0); if ($stabileId <= 0) { $this->error('Serve --stabile-id valido.'); return 1; } $yearOpt = $this->option('year'); $year = is_numeric($yearOpt) ? (int) $yearOpt : null; $tipo = strtolower((string) ($this->option('tipo') ?? 'all')); if (! in_array($tipo, ['all', 'ordinaria', 'straordinaria', 'riscaldamento'], true)) { $this->error('Valore --tipo non valido. Usa all|ordinaria|straordinaria|riscaldamento'); return 1; } $dry = (bool) $this->option('dry'); $systemUserId = (int) (User::query()->orderBy('id')->value('id') ?? 0); $query = DB::connection('gescon_import')->table('operazioni'); if ($year) { $query->whereYear('dt_spe', $year); } if ($tipo !== 'all') { $gestioneCode = match ($tipo) { 'ordinaria' => 'O', 'straordinaria' => 'S', 'riscaldamento' => 'R', default => null, }; if ($gestioneCode) { $query->where('gestione', $gestioneCode); } } $rows = $query ->orderBy('dt_spe') ->orderBy('id_operaz') ->get([ 'id_operaz', 'dt_spe', 'benef', 'num_fat', 'gestione', 'n_stra', ]); $created = 0; $updated = 0; $unchanged = 0; foreach ($rows as $row) { $legacyId = (int) ($row->id_operaz ?? 0); if ($legacyId <= 0) { continue; } $dataReg = ! empty($row->dt_spe) ? (string) $row->dt_spe : now()->toDateString(); $anno = (int) substr($dataReg, 0, 4); $tipoGestione = match (strtoupper((string) ($row->gestione ?? 'O'))) { 'S' => 'straordinaria', 'R' => 'riscaldamento', default => 'ordinaria', }; $gestioneQuery = GestioneContabile::query() ->where('stabile_id', $stabileId) ->where('anno_gestione', $anno) ->where('tipo_gestione', $tipoGestione); if ($tipoGestione === 'straordinaria') { $nStra = is_numeric($row->n_stra ?? null) ? (int) $row->n_stra : null; if ($nStra && $nStra > 0) { $gestioneQuery->where('numero_straordinaria', $nStra); } } $gestione = $gestioneQuery ->orderByDesc('id') ->first(); $resolvedGestioneId = $gestione ? Registrazione::resolveGestioneIdOrDefault((int) $gestione->id, $stabileId, $dataReg) : Registrazione::resolveGestioneIdOrDefault(0, $stabileId, $dataReg); $payload = [ 'stabile_id' => $stabileId, 'gestione_id' => $resolvedGestioneId, 'data_registrazione' => $dataReg, 'entry_date' => $dataReg, 'description' => trim((string) ($row->benef ?? 'Operazione legacy #' . $legacyId)), 'document_type' => 'LEGACY_GESCON', 'document_number' => trim((string) ($row->num_fat ?? '')) !== '' ? trim((string) $row->num_fat) : ('LEG-' . $legacyId), 'external_reference' => 'OPERAZIONE_LEGACY:' . $legacyId, 'status' => 'confirmed', ]; if (Schema::hasColumn('contabilita_registrazioni', 'user_id')) { $payload['user_id'] = $systemUserId > 0 ? $systemUserId : null; } if (Schema::hasColumn('contabilita_registrazioni', 'created_by')) { $payload['created_by'] = $systemUserId > 0 ? $systemUserId : null; } if (Schema::hasColumn('contabilita_registrazioni', 'updated_by')) { $payload['updated_by'] = $systemUserId > 0 ? $systemUserId : null; } $existing = Registrazione::query() ->where('stabile_id', $stabileId) ->where('external_reference', $payload['external_reference']) ->first(); if (! $existing) { if (! $dry) { Registrazione::query()->create($payload); } $created++; continue; } $dirty = false; foreach ($payload as $field => $value) { if ((string) ($existing->{$field} ?? '') !== (string) ($value ?? '')) { $existing->{$field} = $value; $dirty = true; } } if (! $dry && $dirty) { if (empty($existing->protocol) || empty($existing->protocollo_completo)) { $existing->applyAutoProtocols(); } $existing->save(); } if ($dirty) { $updated++; } else { $unchanged++; } } $this->info('Sync completato: creati=' . $created . ' aggiornati=' . $updated . ' invariati=' . $unchanged . ($dry ? ' (DRY-RUN)' : '')); return 0; } }