with(['client:id,name,phone', 'vehicle:id,plate,brand,model']); if ($status = $request->query('status')) { $q->where('status', $status); } if ($s = $request->query('search')) { $q->where(function ($qq) use ($s) { $qq->where('number', 'like', "%{$s}%") ->orWhereHas('vehicle', fn ($v) => $v->where('plate', 'like', "%{$s}%")); }); } return response()->json($q->latest()->paginate(min((int) $request->query('per_page', 25), 100))); } public function show(WorkOrder $workOrder): JsonResponse { return response()->json($workOrder->load(['client', 'vehicle', 'master', 'works', 'parts', 'payments'])); } public function store(Request $request): JsonResponse { $data = $request->validate([ 'client_id' => 'required|exists:clients,id', 'vehicle_id' => 'required|exists:vehicles,id', 'master_id' => 'nullable|exists:users,id', 'opened_at' => 'nullable|date', 'mileage_in' => 'nullable|integer|min:0', 'complaint' => 'nullable|string', 'status' => 'in:new,diagnosis,agreement,approved,in_work,awaiting_parts,ready,done,cancelled', ]); $tenantId = app(TenantManager::class)->currentId(); $data['number'] = WorkOrder::generateNumber($tenantId); $data['opened_at'] ??= now(); $data['status'] ??= 'new'; $data['pay_status'] = 'unpaid'; $data['discount_pct'] = 0; $data['total'] = 0; $wo = WorkOrder::create($data); return response()->json($wo, 201); } public function update(Request $request, WorkOrder $workOrder): JsonResponse { $data = $request->validate([ 'status' => 'sometimes|in:new,diagnosis,agreement,approved,in_work,awaiting_parts,ready,done,cancelled', 'mileage_out' => 'nullable|integer|min:0', 'diagnosis' => 'nullable|string', 'recommendations' => 'nullable|string', 'discount_pct' => 'nullable|numeric|min:0|max:100', ]); $workOrder->update($data); $workOrder->recalcTotal(); return response()->json($workOrder->fresh()); } public function destroy(WorkOrder $workOrder): JsonResponse { $workOrder->delete(); return response()->json(['ok' => true]); } }