| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- <?php
- namespace App\Http\Controllers;
- use App\Jobs\Export\ExportYearDataJob;
- use App\Jobs\Import\ImportYearDataJob;
- use App\Models\Contract;
- use App\Models\File;
- use App\Models\MafOrder;
- use App\Models\Order;
- use App\Models\Product;
- use App\Models\ProductSKU;
- use App\Models\Reclamation;
- use App\Models\Schedule;
- use App\Models\Ttn;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\RedirectResponse;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Storage;
- use Illuminate\Support\Str;
- use Illuminate\View\View;
- class YearDataController extends Controller
- {
- public function index(): View
- {
- return view('year-data.index', [
- 'active' => 'year-data',
- 'years' => $this->getAvailableYears(),
- 'exports' => $this->getRecentExports(),
- ]);
- }
- public function stats(Request $request): JsonResponse
- {
- $year = (int) $request->input('year');
- if ($year < 2020 || $year > 2100) {
- return response()->json(['error' => 'Некорректный год'], 422);
- }
- $stats = $this->collectStats($year);
- return response()->json([
- 'year' => $year,
- 'stats' => $stats,
- 'total' => array_sum($stats),
- ]);
- }
- public function export(Request $request): RedirectResponse
- {
- $year = (int) $request->input('year');
- if ($year < 2020 || $year > 2100) {
- return redirect()->back()->with('danger', 'Некорректный год');
- }
- ExportYearDataJob::dispatch($year, $request->user()->id);
- return redirect()->route('year-data.index')
- ->with('success', "Экспорт данных за {$year} год запущен. Вы получите уведомление о завершении.");
- }
- public function import(Request $request): RedirectResponse
- {
- $request->validate([
- 'year' => 'required|integer|min:2020|max:2100',
- 'import_file' => 'required|file|mimes:zip',
- ]);
- $year = (int) $request->input('year');
- $clearExisting = $request->boolean('clear_existing');
- // Сохраняем загруженный файл
- $file = $request->file('import_file');
- $path = 'import/year_data/' . Str::uuid() . '.zip';
- Storage::disk('public')->put($path, $file->getContent());
- $fullPath = storage_path('app/public/' . $path);
- ImportYearDataJob::dispatch($fullPath, $year, $request->user()->id, $clearExisting);
- $message = "Импорт данных за {$year} год запущен.";
- if ($clearExisting) {
- $message .= " Существующие данные будут очищены.";
- }
- $message .= " Вы получите уведомление о завершении.";
- return redirect()->route('year-data.index')->with('success', $message);
- }
- public function download(File $file)
- {
- if (!$file->path || !Storage::disk('public')->exists($file->path)) {
- abort(404, 'Файл не найден');
- }
- return Storage::disk('public')->download($file->path, $file->original_name);
- }
- private function getAvailableYears(): array
- {
- $years = [];
- $orderYears = Order::withoutGlobalScopes()->withTrashed()
- ->selectRaw('DISTINCT year')
- ->pluck('year')
- ->toArray();
- $productYears = Product::withoutGlobalScopes()->withTrashed()
- ->selectRaw('DISTINCT year')
- ->pluck('year')
- ->toArray();
- $mafOrderYears = MafOrder::withoutGlobalScopes()->withTrashed()
- ->selectRaw('DISTINCT year')
- ->pluck('year')
- ->toArray();
- $contractYears = Contract::selectRaw('DISTINCT year')
- ->pluck('year')
- ->toArray();
- $ttnYears = Ttn::selectRaw('DISTINCT year')
- ->pluck('year')
- ->toArray();
- $years = array_unique(array_merge($orderYears, $productYears, $mafOrderYears, $contractYears, $ttnYears));
- rsort($years);
- return $years;
- }
- private function getRecentExports(): \Illuminate\Database\Eloquent\Collection
- {
- return File::where('original_name', 'like', 'year_data_%')
- ->where('mime_type', 'application/zip')
- ->orderBy('created_at', 'desc')
- ->limit(10)
- ->get();
- }
- private function collectStats(int $year): array
- {
- $orderIds = Order::withoutGlobalScopes()->withTrashed()->where('year', $year)->pluck('id');
- $productIds = Product::withoutGlobalScopes()->withTrashed()->where('year', $year)->pluck('id');
- $mafOrderIds = MafOrder::withoutGlobalScopes()->withTrashed()->where('year', $year)->pluck('id');
- $productSkuIds = ProductSKU::withoutGlobalScopes()->withTrashed()->where('year', $year)->pluck('id');
- $reclamationCount = Reclamation::whereIn('order_id', $orderIds)->count();
- $fileIds = $this->collectFileIds($year, $orderIds, $productIds, $productSkuIds);
- return [
- 'Заказы (Orders)' => $orderIds->count(),
- 'Заказы МАФ (MafOrders)' => $mafOrderIds->count(),
- 'Продукты (Products)' => $productIds->count(),
- 'SKU продуктов (ProductSKU)' => $productSkuIds->count(),
- 'Рекламации (Reclamations)' => $reclamationCount,
- 'Расписания (Schedules)' => Schedule::whereIn('order_id', $orderIds)->count(),
- 'ТТН (Ttns)' => Ttn::where('year', $year)->count(),
- 'Контракты (Contracts)' => Contract::where('year', $year)->count(),
- 'Файлы (Files)' => $fileIds->count(),
- ];
- }
- private function collectFileIds(int $year, $orderIds, $productIds, $productSkuIds): \Illuminate\Support\Collection
- {
- $fileIds = collect();
- $fileIds = $fileIds->merge(
- DB::table('order_photo')->whereIn('order_id', $orderIds)->pluck('file_id')
- );
- $fileIds = $fileIds->merge(
- DB::table('order_document')->whereIn('order_id', $orderIds)->pluck('file_id')
- );
- $fileIds = $fileIds->merge(
- DB::table('order_statement')->whereIn('order_id', $orderIds)->pluck('file_id')
- );
- $reclamationIds = Reclamation::whereIn('order_id', $orderIds)->pluck('id');
- $fileIds = $fileIds->merge(
- DB::table('reclamation_photo_before')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
- );
- $fileIds = $fileIds->merge(
- DB::table('reclamation_photo_after')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
- );
- $fileIds = $fileIds->merge(
- DB::table('reclamation_document')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
- );
- $fileIds = $fileIds->merge(
- DB::table('reclamation_act')->whereIn('reclamation_id', $reclamationIds)->pluck('file_id')
- );
- $fileIds = $fileIds->merge(
- Product::withoutGlobalScopes()->withTrashed()
- ->whereIn('id', $productIds)
- ->whereNotNull('certificate_id')
- ->pluck('certificate_id')
- );
- $fileIds = $fileIds->merge(
- ProductSKU::withoutGlobalScopes()->withTrashed()
- ->whereIn('id', $productSkuIds)
- ->whereNotNull('passport_id')
- ->pluck('passport_id')
- );
- $fileIds = $fileIds->merge(
- Ttn::where('year', $year)->whereNotNull('file_id')->pluck('file_id')
- );
- return $fileIds->unique();
- }
- }
|