withCount('deals'); if ($request->search) { $query->where('name', 'like', "%{$request->search}%"); } if ($request->filled('is_active')) { $query->where('is_active', filter_var($request->is_active, FILTER_VALIDATE_BOOLEAN)); } return response()->json($query->latest()->paginate(min((int) $request->get('per_page', 15), 100))); } public function store(Request $request): JsonResponse { Gate::authorize('create', Product::class); $product = Product::create($this->validated($request) + ['created_by' => auth()->id()]); ActivityLogger::log('product_created', "Product {$product->name} created", $product); return response()->json($product->load('salesScript:id,title'), 201); } public function show(Product $product): JsonResponse { Gate::authorize('view', $product); return response()->json($product->load('salesScript.sections', 'deals:id,title,product_id,status')); } public function update(Request $request, Product $product): JsonResponse { Gate::authorize('update', $product); $product->update($this->validated($request, true)); ActivityLogger::log('product_updated', "Product {$product->name} updated", $product); return response()->json($product->fresh('salesScript:id,title')); } public function destroy(Product $product): JsonResponse { Gate::authorize('delete', $product); $product->delete(); ActivityLogger::log('product_deleted', "Product {$product->id} deleted"); return response()->json(['message' => 'محصول/خدمت حذف شد']); } private function validated(Request $request, bool $partial = false): array { $sometimes = $partial ? 'sometimes|' : ''; return $request->validate([ 'name' => $sometimes.'required|string|max:255', 'category' => 'nullable|string|max:120', 'base_price' => 'nullable|numeric|min:0', 'description' => 'nullable|string', 'is_active' => 'nullable|boolean', 'sales_script_id' => 'nullable|exists:sales_scripts,id', 'faq' => 'nullable|array', 'objection_handling' => 'nullable|array', ]); } }