ClearYearDataJob.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. namespace App\Jobs;
  3. use App\Events\SendWebSocketMessageEvent;
  4. use App\Models\Contract;
  5. use App\Models\File;
  6. use App\Models\MafOrder;
  7. use App\Models\Order;
  8. use App\Models\Product;
  9. use App\Models\ProductSKU;
  10. use App\Models\Reclamation;
  11. use App\Models\Schedule;
  12. use App\Models\Ttn;
  13. use Exception;
  14. use Illuminate\Contracts\Queue\ShouldQueue;
  15. use Illuminate\Foundation\Queue\Queueable;
  16. use Illuminate\Support\Facades\DB;
  17. use Illuminate\Support\Facades\Log;
  18. use Illuminate\Support\Facades\Storage;
  19. class ClearYearDataJob implements ShouldQueue
  20. {
  21. use Queueable;
  22. public function __construct(
  23. private readonly int $year,
  24. private readonly int $userId,
  25. ) {}
  26. public function handle(): void
  27. {
  28. try {
  29. DB::beginTransaction();
  30. $this->clearData();
  31. DB::commit();
  32. Log::info("Clear year data job done for year {$this->year}");
  33. event(new SendWebSocketMessageEvent(
  34. "Данные за {$this->year} год успешно удалены!",
  35. $this->userId,
  36. ['success' => true, 'year' => $this->year]
  37. ));
  38. } catch (Exception $e) {
  39. DB::rollBack();
  40. Log::error("Clear year data job failed for year {$this->year}: " . $e->getMessage());
  41. event(new SendWebSocketMessageEvent(
  42. "Ошибка удаления данных за {$this->year} год: " . $e->getMessage(),
  43. $this->userId,
  44. ['error' => $e->getMessage(), 'year' => $this->year]
  45. ));
  46. }
  47. }
  48. private function clearData(): void
  49. {
  50. $orderIds = Order::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->pluck('id');
  51. $productIds = Product::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->pluck('id');
  52. $productSkuIds = ProductSKU::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->pluck('id');
  53. $reclamationIds = Reclamation::whereIn('order_id', $orderIds)->pluck('id');
  54. $fileIds = $this->collectFileIds($orderIds, $productIds, $productSkuIds);
  55. // Рекламации и связанные данные
  56. DB::table('reclamation_details')->whereIn('reclamation_id', $reclamationIds)->delete();
  57. DB::table('reclamation_product_sku')->whereIn('reclamation_id', $reclamationIds)->delete();
  58. DB::table('reclamation_photo_before')->whereIn('reclamation_id', $reclamationIds)->delete();
  59. DB::table('reclamation_photo_after')->whereIn('reclamation_id', $reclamationIds)->delete();
  60. DB::table('reclamation_document')->whereIn('reclamation_id', $reclamationIds)->delete();
  61. DB::table('reclamation_act')->whereIn('reclamation_id', $reclamationIds)->delete();
  62. Reclamation::whereIn('id', $reclamationIds)->delete();
  63. // Связи заказов с файлами
  64. DB::table('order_photo')->whereIn('order_id', $orderIds)->delete();
  65. DB::table('order_document')->whereIn('order_id', $orderIds)->delete();
  66. DB::table('order_statement')->whereIn('order_id', $orderIds)->delete();
  67. // Расписания
  68. Schedule::whereIn('order_id', $orderIds)->delete();
  69. // SKU продуктов
  70. ProductSKU::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->forceDelete();
  71. // Заказы
  72. Order::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->forceDelete();
  73. // Заказы МАФ
  74. MafOrder::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->forceDelete();
  75. // Продукты
  76. Product::withoutGlobalScopes()->withTrashed()
  77. ->whereIn('id', $productIds)
  78. ->update(['certificate_id' => null]);
  79. Product::withoutGlobalScopes()->withTrashed()->where('year', $this->year)->forceDelete();
  80. // ТТН
  81. Ttn::where('year', $this->year)->update(['file_id' => null]);
  82. Ttn::where('year', $this->year)->delete();
  83. // Контракты
  84. Contract::where('year', $this->year)->delete();
  85. // Файлы
  86. $this->deleteFiles($fileIds);
  87. }
  88. private function collectFileIds($orderIds, $productIds, $productSkuIds): \Illuminate\Support\Collection
  89. {
  90. $fileIds = collect();
  91. $fileIds = $fileIds->merge(
  92. DB::table('order_photo')->whereIn('order_id', $orderIds)->pluck('file_id')
  93. );
  94. $fileIds = $fileIds->merge(
  95. DB::table('order_document')->whereIn('order_id', $orderIds)->pluck('file_id')
  96. );
  97. $fileIds = $fileIds->merge(
  98. DB::table('order_statement')->whereIn('order_id', $orderIds)->pluck('file_id')
  99. );
  100. $reclamationIds = Reclamation::whereIn('order_id', $orderIds)->pluck('id');
  101. $fileIds = $fileIds->merge(
  102. DB::table('reclamation_photo_before')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
  103. );
  104. $fileIds = $fileIds->merge(
  105. DB::table('reclamation_photo_after')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
  106. );
  107. $fileIds = $fileIds->merge(
  108. DB::table('reclamation_document')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
  109. );
  110. $fileIds = $fileIds->merge(
  111. DB::table('reclamation_act')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
  112. );
  113. $fileIds = $fileIds->merge(
  114. Product::withoutGlobalScopes()->withTrashed()
  115. ->whereIn('id', $productIds)
  116. ->whereNotNull('certificate_id')
  117. ->pluck('certificate_id')
  118. );
  119. $fileIds = $fileIds->merge(
  120. ProductSKU::withoutGlobalScopes()->withTrashed()
  121. ->whereIn('id', $productSkuIds)
  122. ->whereNotNull('passport_id')
  123. ->pluck('passport_id')
  124. );
  125. $fileIds = $fileIds->merge(
  126. Ttn::where('year', $this->year)->whereNotNull('file_id')->pluck('file_id')
  127. );
  128. return $fileIds->unique();
  129. }
  130. private function deleteFiles($fileIds): void
  131. {
  132. $files = File::whereIn('id', $fileIds)->get();
  133. foreach ($files as $file) {
  134. if ($file->path && Storage::disk('public')->exists($file->path)) {
  135. Storage::disk('public')->delete($file->path);
  136. }
  137. }
  138. File::whereIn('id', $fileIds)->delete();
  139. }
  140. }