query('search', '')); $status = trim((string) $request->query('status', '')); $perPage = $this->perPage($request); $orders = StockOrder::query() ->with(['item.imageFile', 'user']) ->withSum(['reservations as active_reservations_sum_quantity' => fn ($query) => $query->active()], 'quantity') ->when($search !== '', function (Builder $query) use ($search): void { $query->where(function (Builder $query) use ($search): void { $query->where('order_number', 'like', "%{$search}%") ->orWhere('note', 'like', "%{$search}%") ->orWhereHas('item', fn (Builder $query) => $query ->where('article', 'like', "%{$search}%") ->orWhere('calculator_name', 'like', "%{$search}%")); }); }) ->when(array_key_exists($status, StockOrder::STATUS_NAMES), fn (Builder $query) => $query->where('status', $status)) ->orderByDesc('created_at') ->paginate($perPage) ->withQueryString(); return view('stock.orders', [ 'active' => 'stock_orders', 'orders' => $orders, 'items' => CommonCatalogItem::query() ->orderBy('article') ->orderBy('calculator_name') ->get(['id', 'article', 'calculator_name']), 'orderedOrderNumbers' => StockOrder::query() ->where('status', StockOrder::STATUS_ORDERED) ->whereNotNull('order_number') ->where('order_number', '<>', '') ->distinct() ->orderBy('order_number') ->pluck('order_number'), 'statuses' => StockOrder::STATUS_NAMES, 'search' => $search, 'status' => $status, 'per_page' => $perPage, ]); } public function store(StoreStockOrderRequest $request): RedirectResponse { /** @var User $actor */ $actor = $request->user(); $this->inventoryService->createOrder($request->validated(), $actor); return back()->with('success', 'Складской заказ создан.'); } public function update(StoreStockOrderRequest $request, StockOrder $stockOrder): RedirectResponse { /** @var User $actor */ $actor = $request->user(); try { $this->inventoryService->updateOrder($stockOrder, $request->validated(), $actor); return back()->with('success', 'Складской заказ обновлён.'); } catch (DomainException $exception) { return back()->with('error', $exception->getMessage()); } } public function setOrderInStock(Request $request): RedirectResponse { $validated = $request->validate([ 'bulk_order_number' => ['required', 'string', 'max:255'], ]); /** @var User $actor */ $actor = $request->user(); try { $count = $this->inventoryService->setOrderInStock( trim((string) $validated['bulk_order_number']), $actor, ); return back()->with('success', "Позиции заказа переведены в статус «На складе»: {$count}."); } catch (DomainException $exception) { return back() ->withErrors(['bulk_order_number' => $exception->getMessage()]) ->withInput(); } } public function destroy(StockOrder $stockOrder): RedirectResponse { if ($stockOrder->reservations()->exists()) { return back()->with('error', 'Нельзя удалить заказ с историей бронирований.'); } $stockOrder->delete(); return back()->with('success', 'Складской заказ удалён.'); } public function import(Request $request): RedirectResponse { $validated = $request->validate([ 'import_file' => ['required', 'file', 'mimes:xlsx', 'max:10240'], ]); /** @var UploadedFile $uploadedFile */ $uploadedFile = $validated['import_file']; $filename = Storage::disk('upload')->putFile('stock_orders', $uploadedFile); $import = Import::query()->create([ 'type' => 'stock_orders', 'year' => null, 'filename' => $filename, 'status' => 'new', 'user_id' => $request->user()?->id, 'file_path' => $filename, 'original_filename' => $uploadedFile->getClientOriginalName(), ]); ImportJob::dispatch($import, (int) $request->user()?->id); return back()->with('success', 'Импорт складских заказов поставлен в очередь.'); } private function perPage(Request $request): int { $allowed = [50, 100, 200, 500, 2000]; $perPage = (int) $request->query('per_page', session('per_page', 50)); $perPage = in_array($perPage, $allowed, true) ? $perPage : 50; session(['per_page' => $perPage]); return $perPage; } }