first(); if($request->ajax()){ Log::info('Products DataTables request received'); Log::info('Request parameters:', $request->all()); try { // Check if products exist $productCount = Product::count(); Log::info('Total products in database: ' . $productCount); $data = Product::with(['category', 'stocks']) ->select(['id', 'code', 'name', 'product_category_id', 'unit', 'active']); Log::info('Query built, executing DataTables...'); return DataTables::of($data) ->addIndexColumn() ->addColumn('code', function ($row) { return $row->code; }) ->addColumn('name', function ($row) { return $row->name; }) ->addColumn('category_name', function ($row) { return $row->category ? $row->category->name : '-'; }) ->addColumn('unit', function ($row) { return $row->unit ?? '-'; }) ->addColumn('total_stock', function ($row){ try { $totalStock = $row->stocks()->sum('quantity'); return number_format($totalStock, 2); } catch (\Exception $e) { Log::error('Error calculating total stock for product ' . $row->id . ': ' . $e->getMessage()); return '0.00'; } }) ->addColumn('action', function ($row) use ($menu) { $btn = '
'; if (Gate::allows('update', $menu)) { $btn .= 'Edit'; $btn .= ''; } $btn .= ''; $btn .= '
'; return $btn; }) ->filterColumn('category_name', function($query, $keyword) { $query->whereHas('category', function($q) use ($keyword) { $q->where('name', 'like', "%{$keyword}%"); }); }) ->orderColumn('code', function ($query, $order) { $query->orderBy('products.code', $order); }) ->orderColumn('name', function ($query, $order) { $query->orderBy('products.name', $order); }) ->orderColumn('category_name', function ($query, $order) { $query->orderBy( DB::raw('(SELECT name FROM product_categories WHERE product_categories.id = products.product_category_id)'), $order ); }) ->orderColumn('unit', function ($query, $order) { $query->orderBy('products.unit', $order); }) ->rawColumns(['action']) ->make(true); } catch (\Exception $e) { Log::error('Products DataTables error: ' . $e->getMessage()); Log::error('Stack trace: ' . $e->getTraceAsString()); return response()->json(['error' => 'Failed to load data'], 500); } } 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) { try{ $request->validate([ 'code' => [ 'required', 'string', Rule::unique('products')->whereNull('deleted_at'), ], 'name' => 'required|string', 'description' => 'nullable|string', 'unit' => 'nullable|string', 'active' => 'required|boolean', 'product_category_id' => 'required|exists:product_categories,id' ]); // Create product $product = Product::create([ 'code' => $request->code, 'name' => $request->name, 'unit' => $request->unit, 'active' => $request->active, 'description' => $request->description, 'product_category_id' => $request->product_category_id, ]); return redirect()->route('products.index')->with('success', 'Produk berhasil ditambahkan.'); }catch(\Exception $ex){ Log::error($ex->getMessage()); throw $ex; } } /** * 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) { try{ $request->validate([ 'code' => [ 'required', 'string', Rule::unique('products')->ignore($product->id)->whereNull('deleted_at'), ], 'name' => 'required|string', 'description' => 'nullable|string', 'unit' => 'nullable|string', 'active' => 'required|boolean', 'product_category_id' => 'required|exists:product_categories,id' ]); $product->update($request->only(['code', 'name', 'description', 'unit','active', 'product_category_id'])); return redirect()->route('products.index')->with('success', 'Produk berhasil diperbarui.'); }catch(\Exception $ex){ Log::error($ex->getMessage()); } } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy(Product $product) { $product->delete(); return redirect()->route('products.index')->with('success', 'Produk berhasil dihapus.'); } public function toggleActive(Request $request, Product $product) { $product->active = !$product->active; $product->save(); return response()->json([ 'success' => true, 'active' => $product->active, 'message' => 'Status produk berhasil diperbarui.' ]); } public function all_products(){ try{ $products = Product::where('active', true)->select('id','name')->get(); return response()->json($products); }catch(\Exception $ex){ Log::error($ex->getMessage()); } } public function dealers_stock(Request $request){ $productId = $request->get('product_id'); $product = Product::with(['stocks.dealer'])->findOrFail($productId); $data = $product->stocks->map(function ($stock) { return [ 'dealer_name' => $stock->dealer->name ?? '-', 'quantity' => $stock->quantity ]; }); return DataTables::of($data)->make(true); } public function exportDealersStock() { try { $fileName = 'stok_produk_dealers_' . date('Y-m-d_H-i-s') . '.xlsx'; return Excel::download(new ProductStockDealers(), $fileName); } catch (\Exception $e) { Log::error('Export dealers stock error: ' . $e->getMessage()); return back()->with('error', 'Gagal mengexport data. Silakan coba lagi.'); } } }