netgescon-day0/app/Services/GesconImport/EssentialImportService.php

153 lines
6.8 KiB
PHP

<?php
namespace App\Services\GesconImport;
use App\Models\Amministratore;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
use App\Models\GesconImportMapping;
use App\Services\GesconImport\StabileEnrichmentService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
/**
* Orchestratore leggero per i tre archivi essenziali: stabili, gestioni, banche.
* Evita di passare dalla pipeline completa quando non necessario.
*/
class EssentialImportService
{
public function importStabileCore(Amministratore $amm, string $legacyCode, array $options = []): array
{
$params = ['--stabile' => $legacyCode, '--solo' => 'stabili', '--path' => $options['path'] ?? '/mnt/gescon-archives/gescon'];
if (!empty($options['dry'])) $params['--dry-run'] = true;
if (!empty($options['limit'])) $params['--limit'] = (int)$options['limit'];
Artisan::call('gescon:import-full', $params);
$out = Artisan::output();
$counts = $this->parseCounts($out);
$this->touchMapping($legacyCode, $counts, !empty($options['dry']));
// Enrichment (solo se non dry)
$enrichment = [];
if (empty($options['dry'])) {
try {
$enrichment = (new StabileEnrichmentService())->enrich($legacyCode, $options['path'] ?? '/mnt/gescon-archives/gescon');
} catch (\Throwable $e) {
Log::warning('EssentialImportService enrichment error: ' . $e->getMessage());
}
}
return ['step' => 'stabili'] + $counts + ['output' => $out, 'enrichment' => $enrichment];
}
public function importGestioni(Amministratore $amm, string $legacyCode, array $options = []): array
{
$root = $options['path'] ?? '/mnt/gescon-archives/gescon';
$params = ['--stabile' => $legacyCode, '--root' => $root];
if (!empty($options['force_months'])) $params['--force-update-months'] = true;
if (!empty($options['dry'])) $params['--dry-run'] = true;
Artisan::call('gescon:import-gestioni', $params);
$out = Artisan::output();
return ['step' => 'gestioni', 'output' => $out];
}
public function importBanche(Amministratore $amm, string $legacyCode, array $options = []): array
{
$params = ['--stabile' => $legacyCode, '--solo' => 'banche', '--path' => $options['path'] ?? '/mnt/gescon-archives/gescon'];
if (!empty($options['dry'])) $params['--dry-run'] = true;
Artisan::call('gescon:import-full', $params);
$out = Artisan::output();
return ['step' => 'banche', 'output' => $out];
}
public function runAll(Amministratore $amm, string $legacyCode, array $options = []): array
{
$agg = [];
$agg[] = $this->importStabileCore($amm, $legacyCode, $options);
if (empty($options['dry'])) {
$agg[] = $this->importGestioni($amm, $legacyCode, $options);
$agg[] = $this->importBanche($amm, $legacyCode, $options);
}
return $agg;
}
/** Calcola hash del record staging principale per stabile (per rilevare cambi). */
private function computeStabileHash(string $legacyCode, string $basePath): ?string
{
try {
$parts = [];
if (Schema::connection('gescon_import')->hasTable('stabili')) {
$r = DB::connection('gescon_import')->table('stabili')->where('cod_stabile', $legacyCode)->first();
if ($r) $parts[] = json_encode($r);
}
if (Schema::connection('gescon_import')->hasTable('condomin')) {
$r2 = DB::connection('gescon_import')->table('condomin')->where('cod_stabile', $legacyCode)->first();
if ($r2) $parts[] = json_encode($r2);
}
if (!$parts) return null;
return substr(hash('sha256', implode('|', $parts)), 0, 40);
} catch (\Throwable $e) {
return null;
}
}
/** Sincronizza uno stabile se i dati di staging sono cambiati; opzionale banche/gestioni. */
public function syncStabile(Amministratore $amm, string $legacyCode, array $options = []): array
{
$path = $options['path'] ?? '/mnt/gescon-archives/gescon';
$dry = !empty($options['dry']);
$currentHash = $this->computeStabileHash($legacyCode, $path);
$mapping = GesconImportMapping::where('legacy_code', $legacyCode)->where('user_id', Auth::id())->first();
$prevHash = $mapping ? ($mapping->meta['stabile_hash'] ?? null) : null;
if ($currentHash && $currentHash === $prevHash) {
// Nulla da fare (ma arricchimento facoltativo)
if (empty($dry)) {
try {
$enr = (new StabileEnrichmentService())->enrich($legacyCode, $path);
} catch (\Throwable $e) {
$enr = ['error' => $e->getMessage()];
}
} else {
$enr = [];
}
return ['changed' => false, 'hash' => $currentHash, 'enrichment' => $enr];
}
$steps = [];
$steps[] = $this->importStabileCore($amm, $legacyCode, $options);
if (!$dry && !empty($options['with_gestioni'])) $steps[] = $this->importGestioni($amm, $legacyCode, $options);
if (!$dry && !empty($options['with_banche'])) $steps[] = $this->importBanche($amm, $legacyCode, $options);
// aggiorna hash
if ($mapping) {
$meta = $mapping->meta ?? [];
if ($currentHash) $meta['stabile_hash'] = $currentHash;
$mapping->meta = $meta;
$mapping->save();
}
return ['changed' => true, 'new_hash' => $currentHash, 'steps' => $steps];
}
private function parseCounts(string $out): array
{
$created = 0;
$updated = 0;
if (preg_match('/creati\s*:\s*(\d+)/i', $out, $m)) $created = (int)$m[1];
if (preg_match('/aggiornati\s*:\s*(\d+)/i', $out, $m)) $updated = (int)$m[1];
return ['created' => $created, 'updated' => $updated];
}
private function touchMapping(string $legacyCode, array $counts, bool $dry): void
{
try {
$mapping = GesconImportMapping::firstOrCreate(['user_id' => Auth::id(), 'legacy_code' => $legacyCode], ['status' => 'pending']);
$mapping->status = $dry ? 'dry-run' : 'synced';
$mapping->last_dry_run_at = $dry ? Carbon::now() : $mapping->last_dry_run_at;
$mapping->last_sync_at = $dry ? $mapping->last_sync_at : Carbon::now();
$meta = $mapping->meta ?? [];
$meta['last_core_counts'] = $counts;
$mapping->meta = $meta;
$mapping->save();
} catch (\Throwable $e) {
Log::warning('EssentialImportService touchMapping failed: ' . $e->getMessage());
}
}
}