'spare_parts', 'title' => 'Справочник расшифровок', 'id' => 'pricing_codes', 'header' => [ 'id' => 'ID', 'type' => 'Тип', 'code' => 'Код', 'description' => 'Расшифровка', 'actions' => 'Действия', ], ]; public function index(Request $request) { $this->setSortAndOrderBy(new PricingCode(), $request); $sortBy = $request->get('sortBy', 'code'); $allowedSort = ['id', 'type', 'code', 'description']; if (!in_array($sortBy, $allowedSort, true)) { $sortBy = 'code'; } $orderBy = $request->get('order') === 'desc' ? 'desc' : 'asc'; $q = PricingCode::query(); // Поиск $search = $request->get('s', $request->get('search')); if (!empty($search)) { $q->where(function ($query) use ($search) { $query->where('code', 'LIKE', '%' . $search . '%') ->orWhere('description', 'LIKE', '%' . $search . '%') ->orWhere('type', 'LIKE', '%' . $search . '%'); }); } $q->orderBy($sortBy, $orderBy); if ($sortBy !== 'id') { $q->orderBy('id', $orderBy); } $this->data['pricing_codes'] = $q->paginate($this->data['per_page'])->withQueryString(); $this->data['sortBy'] = $sortBy; $this->data['orderBy'] = $orderBy; $this->data['searchFields'] = ['type', 'code', 'description']; $this->data['search'] = $search; return view('pricing_codes.index', $this->data); } public function store(Request $request): RedirectResponse { $request->validate([ 'type' => 'required|in:tsn_number,pricing_code', 'code' => 'required|string', 'description' => 'nullable|string', ]); // Проверяем уникальность комбинации type + code $exists = PricingCode::where('type', $request->type) ->where('code', $request->code) ->exists(); if ($exists) { return redirect()->route('pricing_codes.index') ->with(['error' => 'Такой код уже существует для данного типа!']); } PricingCode::create($request->only(['type', 'code', 'description'])); return redirect()->route('pricing_codes.index') ->with(['success' => 'Код расценки успешно добавлен!']); } public function update(Request $request, PricingCode $pricingCode): RedirectResponse { $request->validate([ 'description' => 'nullable|string', ]); $pricingCode->update(['description' => $request->get('description')]); return redirect()->route('pricing_codes.index') ->with(['success' => 'Расшифровка успешно обновлена!']); } public function destroy(PricingCode $pricingCode): RedirectResponse { $pricingCode->delete(); return redirect()->route('pricing_codes.index') ->with(['success' => 'Код расценки успешно удалён!']); } /** * API метод для получения расшифровки кода */ public function getDescription(Request $request) { $type = $request->get('type'); $code = $request->get('code'); if (!$type || !$code) { return response()->json(['description' => null]); } $description = null; if ($type === 'tsn_number') { $description = PricingCode::getTsnDescription($code); } elseif ($type === 'pricing_code') { $description = PricingCode::getPricingCodeDescription($code); } return response()->json(['description' => $description]); } /** * API метод для поиска кодов (autocomplete) */ public function search(Request $request) { $type = $request->get('type'); $query = $request->get('query', ''); if (!$type) { return response()->json([]); } $codes = PricingCode::where('type', $type) ->where(function ($q) use ($query) { $q->where('code', 'LIKE', '%' . $query . '%') ->orWhere('description', 'LIKE', '%' . $query . '%'); }) ->orderBy('code') ->limit(20) ->get(['code', 'description']); return response()->json($codes); } }