first(); if($request->ajax()){ $data = Product::with(['category','dealers']); return DataTables::of($data) ->addIndexColumn() ->addColumn('category_name', function ($row) { return $row->category ? $row->category->name : '-'; }) ->addColumn('total_stock', function ($row){ return $row->dealers->sum(function($dealer){ return $dealer->pivot->quantity ?? 0; }); }) ->addColumn('action', function ($row) use ($menu) { $btn = '
'; if (Auth::user()->can('delete', $menu)) { $btn .= ''; } if (Auth::user()->can('update', $menu)) { $btn .= 'Edit'; } $btn .= '
'; return $btn; }) ->rawColumns(['action']) ->make(true); } return view('warehouse_management.products.index'); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { $categories = ProductCategory::with('children')->whereNull('parent_id')->get(); $dealers = Dealer::all(); return view('warehouse_management.products.create', compact('categories', 'dealers')); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $request->validate([ 'code' => 'required|string|unique:products,code', 'name' => 'required|string', 'description' => 'nullable|string', 'product_category_id' => 'required|exists:product_categories,id', 'dealer_stock' => 'nullable|array', 'dealer_stock.*.dealer_id' => 'required|exists:dealers,id', 'dealer_stock.*.quantity' => 'required|integer|min:0', ]); // Create product $product = Product::create([ 'code' => $request->code, 'name' => $request->name, 'description' => $request->description, 'product_category_id' => $request->product_category_id, ]); // Prepare dealer stock for pivot $pivotData = []; if ($request->has('dealer_stock')) { foreach ($request->dealer_stock as $stockData) { if (empty($stockData['dealer_id']) || !isset($stockData['quantity'])) continue; $pivotData[$stockData['dealer_id']] = ['quantity' => $stockData['quantity']]; } // Attach dealer stock using pivot table $product->dealers()->attach($pivotData); } return redirect()->route('products.index')->with('success', 'Produk berhasil ditambahkan.'); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $product = Product::findOrFail($id); return view('warehouse_management.products.edit', [ 'product' => $product->load('dealers'), 'dealers' => Dealer::all(), 'categories' => ProductCategory::with('children')->get(), ]); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, Product $product) { $request->validate([ 'code' => 'required|string|unique:products,code,' . $product->id, 'name' => 'required|string', 'description' => 'nullable|string', 'product_category_id' => 'required|exists:product_categories,id', 'dealer_stock' => 'nullable|array', 'dealer_stock.*.dealer_id' => 'required|exists:dealers,id', 'dealer_stock.*.quantity' => 'required|integer|min:0', ]); $product->update($request->only(['code', 'name', 'description', 'product_category_id'])); // Prepare pivot sync data $syncData = []; if ($request->has('dealer_stock')) { foreach ($request->dealer_stock as $item) { $syncData[$item['dealer_id']] = ['quantity' => $item['quantity']]; } } // Sync with pivot table $product->dealers()->sync($syncData); return redirect()->route('products.index')->with('success', 'Produk berhasil diperbarui.'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy(Product $product) { // Detach all dealer relationships (optional if using cascade on delete) $product->dealers()->detach(); // Delete the product $product->delete(); return response()->json(['success' => true, 'message' => 'Produk berhasil dihapus.']); } }