ADD PricelistCleanup command

This commit is contained in:
E98Developer 2026-05-06 21:11:51 +02:00
parent 5ad60e27e4
commit 951340e564

View File

@ -0,0 +1,181 @@
<?php
namespace App\Console\Commands;
use App\Models\Attachment;
use App\Models\PriceList;
use App\Models\PricelistFile;
use App\Models\PricelistFileLine;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class PricelistCleanup extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'pricelist:cleanup {date : A dátum, ami előtti árlistákat törölni kell (YYYY-MM-DD)} {--dry-run : Csak szimuláció, nem töröl semmit}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Árlisták és kapcsolódó adatok törlése egy adott dátum előtt.';
/**
* Execute the console command.
*/
public function handle(): int
{
$date = $this->argument('date');
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
$this->error('Érvénytelen dátum formátum. Használd az YYYY-MM-DD formátumot.');
return 1;
}
$dryRun = $this->option('dry-run');
// Számlálás
$priceListsCount = PriceList::where('available', '<', $date)->count();
$priceListPricesCount = DB::table('price_list_prices')
->whereIn('price_list_id', function ($query) use ($date) {
$query->select('id')->from('price_lists')->where('available', '<', $date);
})->count();
$pricelistFilesCount = PricelistFile::where('available_date', '<', $date)->count();
$pricelistFileLinesCount = PricelistFileLine::whereIn('pricelist_file_id', function ($query) use ($date) {
$query->select('id')->from('pricelist_files')->where('available_date', '<', $date);
})->count();
$attachmentsCount = Attachment::whereIn('attachable_id', function ($query) use ($date) {
$query->select('id')->from('price_lists')->where('available', '<', $date);
})->where('attachable_type', PriceList::class)
->orWhere(function($query) use ($date) {
$query->whereIn('attachable_id', function ($subQuery) use ($date) {
$subQuery->select('id')->from('pricelist_files')->where('available_date', '<', $date);
})->where('attachable_type', PricelistFile::class);
})->count();
$this->info("Törlendő elemek száma ($date előtt):");
$this->table(
['Típus', 'Darabszám'],
[
['Árlisták (price_lists)', $priceListsCount],
['Árlista árak (price_list_prices)', $priceListPricesCount],
['Árlista fájlok (pricelist_files)', $pricelistFilesCount],
['Árlista fájl sorok (pricelist_file_lines)', $pricelistFileLinesCount],
['Csatolt fájlok (attachments)', $attachmentsCount],
]
);
if ($dryRun) {
$this->info('Dry-run mód: nem történt törlés.');
return 0;
}
if ($priceListsCount === 0 && $pricelistFilesCount === 0) {
$this->info('Nincs törlendő elem.');
return 0;
}
if (!$this->confirm('Biztosan törölni szeretnéd a megadott elemeket?')) {
$this->info('Művelet megszakítva.');
return 0;
}
$this->info('Törlés megkezdése...');
// PriceLists törlése optimalizáltan
if ($priceListsCount > 0) {
$this->info('Árlisták és kapcsolódó árak törlése...');
$bar = $this->output->createProgressBar($priceListsCount);
$bar->start();
PriceList::where('available', '<', $date)->chunkById(1000, function ($priceLists) use ($bar) {
$ids = $priceLists->pluck('id')->toArray();
// Kapcsolódó árak törlése
DB::table('price_list_prices')->whereIn('price_list_id', $ids)->delete();
// Csatolmányok kezelése
$attachments = Attachment::whereIn('attachable_id', $ids)
->where('attachable_type', PriceList::class)
->get();
$this->deleteAttachments($attachments);
// Maguk a rekordok törlése
PriceList::whereIn('id', $ids)->delete();
$bar->advance($priceLists->count());
});
$bar->finish();
$this->info("");
}
// PricelistFiles törlése optimalizáltan
if ($pricelistFilesCount > 0) {
$this->info('Árlista fájlok és kapcsolódó sorok törlése...');
$bar = $this->output->createProgressBar($pricelistFilesCount);
$bar->start();
PricelistFile::where('available_date', '<', $date)->chunkById(1000, function ($files) use ($bar) {
$ids = $files->pluck('id')->toArray();
// Kapcsolódó sorok törlése
PricelistFileLine::whereIn('pricelist_file_id', $ids)->delete();
// Csatolmányok kezelése
$attachments = Attachment::whereIn('attachable_id', $ids)
->where('attachable_type', PricelistFile::class)
->get();
$this->deleteAttachments($attachments);
// Maguk a rekordok törlése
PricelistFile::whereIn('id', $ids)->delete();
$bar->advance($files->count());
});
$bar->finish();
$this->info("");
}
$this->info('A tisztítás sikeresen befejeződött.');
return 0;
}
/**
* Csatolmányok és fizikai fájlok törlése
*/
protected function deleteAttachments($attachments): void
{
if ($attachments->isEmpty()) {
return;
}
$filePaths = $attachments->map(function ($attachment) {
return $attachment->path . DIRECTORY_SEPARATOR . $attachment->filename;
})->toArray();
// Fizikai fájlok törlése (feltételezve az 'attachments' disket, mint az EmegrendelesCleanup-nál)
try {
Storage::disk('attachments')->delete($filePaths);
} catch (\Exception $e) {
$this->warn('Hiba a fizikai fájlok törlésekor: ' . $e->getMessage());
}
// Attachment rekordok törlése
Attachment::whereIn('id', $attachments->pluck('id'))->delete();
}
}