diff --git a/app/Console/Commands/PricelistCleanup.php b/app/Console/Commands/PricelistCleanup.php new file mode 100644 index 0000000..bdc8bfe --- /dev/null +++ b/app/Console/Commands/PricelistCleanup.php @@ -0,0 +1,181 @@ +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(); + } +}