netgescon-day0/app/Console/Commands/GesconRubricaPurgeImportedCommand.php

201 lines
7.1 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Fornitore;
use App\Models\RubricaContattoCanale;
use App\Models\RubricaRuolo;
use App\Models\RubricaUniversale;
use App\Models\Stabile;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class GesconRubricaPurgeImportedCommand extends Command
{
protected $signature = 'gescon:rubrica-purge-imported
{amministratore_id : ID amministratore}
{--fornitori : Pulisce Fornitori + rubrica collegata}
{--condomin : Pulisce ruoli/legami importati da condomin + rubrica orfana}
{--stabile= : (Solo per --condomin) Codice stabile (es. 0021)}
{--dry-run : Non scrive, mostra solo conteggi}';
protected $description = 'Pulisce in modo sicuro i dati importati in Rubrica (fornitori e/o condomin), senza cancellare contatti ancora collegati altrove.';
public function handle(): int
{
$amministratoreId = (int) $this->argument('amministratore_id');
if ($amministratoreId <= 0) {
$this->error('amministratore_id non valido');
return self::FAILURE;
}
$dry = (bool) $this->option('dry-run');
$doFornitori = (bool) $this->option('fornitori');
$doCondomin = (bool) $this->option('condomin');
$codStabile = trim((string) ($this->option('stabile') ?? ''));
if (!$doFornitori && !$doCondomin) {
$doFornitori = true;
$doCondomin = true;
}
$stats = [
'fornitori_deleted' => 0,
'rubrica_deleted_from_fornitori' => 0,
'ruoli_deleted_from_condomin' => 0,
'rubrica_deleted_from_condomin' => 0,
'rubrica_kept_linked' => 0,
];
$runner = function () use (&$stats, $amministratoreId, $doFornitori, $doCondomin, $codStabile, $dry): void {
$rubricaCandidates = [];
if ($doFornitori) {
$rubricaIds = Fornitore::query()
->where('amministratore_id', $amministratoreId)
->whereNotNull('rubrica_id')
->pluck('rubrica_id')
->map(fn($id) => (int) $id)
->unique()
->values()
->all();
if ($dry) {
$stats['fornitori_deleted'] = Fornitore::query()
->where('amministratore_id', $amministratoreId)
->count();
} else {
$stats['fornitori_deleted'] = Fornitore::query()
->where('amministratore_id', $amministratoreId)
->delete();
}
foreach ($rubricaIds as $id) {
$rubricaCandidates[$id] = true;
}
}
if ($doCondomin) {
$stabileIds = null;
if ($codStabile !== '') {
$stabileIds = Stabile::query()
->where('amministratore_id', $amministratoreId)
->where(function ($q) use ($codStabile) {
$q->where('codice_stabile', $codStabile)
->orWhere('codice_stabile', ltrim($codStabile, '0'));
})
->pluck('id')
->map(fn($id) => (int) $id)
->unique()
->values()
->all();
if (empty($stabileIds)) {
throw new \RuntimeException("Stabile non trovato per codice={$codStabile} e amministratore_id={$amministratoreId}");
}
}
$ruoliQuery = RubricaRuolo::query()
->where('meta->source', 'gescon_import.condomin')
->whereIn('rubrica_id', function ($sub) use ($amministratoreId) {
$sub->select('id')
->from('rubrica_universale')
->where('amministratore_id', $amministratoreId);
});
if (is_array($stabileIds)) {
$ruoliQuery->whereIn('stabile_id', $stabileIds);
}
$rubricaIdsFromRuoli = $ruoliQuery
->pluck('rubrica_id')
->map(fn($id) => (int) $id)
->unique()
->values()
->all();
if ($dry) {
$stats['ruoli_deleted_from_condomin'] = $ruoliQuery->count();
} else {
$stats['ruoli_deleted_from_condomin'] = $ruoliQuery->delete();
}
foreach ($rubricaIdsFromRuoli as $id) {
$rubricaCandidates[$id] = true;
}
}
if (empty($rubricaCandidates)) {
return;
}
foreach (array_keys($rubricaCandidates) as $rubricaId) {
if ($rubricaId <= 0) {
continue;
}
$hasFornitori = Fornitore::query()
->where('amministratore_id', $amministratoreId)
->where('rubrica_id', $rubricaId)
->exists();
$hasStabili = DB::table('stabili')
->where('amministratore_id', $amministratoreId)
->where('rubrica_id', $rubricaId)
->exists();
$hasRuoli = RubricaRuolo::query()
->where('rubrica_id', $rubricaId)
->exists();
$hasCanali = RubricaContattoCanale::query()
->where('rubrica_id', $rubricaId)
->exists();
if ($hasFornitori || $hasStabili || $hasRuoli || $hasCanali) {
$stats['rubrica_kept_linked']++;
continue;
}
$rubrica = RubricaUniversale::query()
->where('amministratore_id', $amministratoreId)
->whereKey($rubricaId)
->first();
if (!$rubrica) {
continue;
}
if ($dry) {
// Simulazione: non scrive.
} else {
// Soft-delete: lascia possibilità di ripristino.
$rubrica->delete();
}
if ($doFornitori && $rubrica->categoria === 'fornitore') {
$stats['rubrica_deleted_from_fornitori']++;
} elseif ($doCondomin && $rubrica->categoria === 'condomino') {
$stats['rubrica_deleted_from_condomin']++;
}
}
};
try {
if ($dry) {
$runner();
} else {
DB::transaction($runner);
}
} catch (\Throwable $e) {
$this->error($e->getMessage());
return self::FAILURE;
}
$this->info('✅ Purge completato' . ($dry ? ' (dry-run)' : ''));
$this->line(json_encode($stats, JSON_UNESCAPED_UNICODE));
return self::SUCCESS;
}
}