middleware('auth'); } public function index() { $query = Pesanan::with(['user', 'barang']) ->where('user_id', Auth::id()); // Filter berdasarkan tanggal if (request('start_date')) { $query->whereDate('created_at', '>=', request('start_date')); } if (request('end_date')) { $query->whereDate('created_at', '<=', request('end_date')); } // Filter berdasarkan status if (request('status')) { $query->where('status', request('status')); } $pesanan = $query->latest()->paginate(10); return view('pesanan.index', compact('pesanan')); } public function create() { $barang = Barang::where('stok', '>', 0)->get(); return view('pesanan.create', compact('barang')); } public function store(Request $request) { $request->validate([ 'barang_id' => 'required|exists:barang,id', 'jumlah' => 'required|integer|min:1', 'catatan' => 'nullable|string' ]); $barang = Barang::findOrFail($request->barang_id); if ($barang->stok < $request->jumlah) { return back()->with('error', 'Stok tidak mencukupi'); } // Cek apakah sudah ada pesanan pending untuk barang yang sama $existingPesanan = Pesanan::where('user_id', Auth::id()) ->where('barang_id', $request->barang_id) ->where('status', 'pending') ->first(); if ($existingPesanan) { // Update jumlah pesanan yang ada $newJumlah = $existingPesanan->jumlah + $request->jumlah; if ($barang->stok < $newJumlah) { return back()->with('error', 'Stok tidak mencukupi untuk total pesanan'); } $existingPesanan->update([ 'jumlah' => $newJumlah, 'total_harga' => $barang->harga * $newJumlah, 'catatan' => $request->catatan ?? $existingPesanan->catatan ]); // Kurangi stok barang $barang->update([ 'stok' => $barang->stok - $request->jumlah ]); return redirect()->route('pesanan.index')->with('success', 'Pesanan berhasil diperbarui'); } // Jika tidak ada pesanan yang sama, buat pesanan baru $total_harga = $barang->harga * $request->jumlah; $pesanan = Pesanan::create([ 'user_id' => Auth::id(), 'barang_id' => $request->barang_id, 'jumlah' => $request->jumlah, 'total_harga' => $total_harga, 'status' => 'pending', 'catatan' => $request->catatan ]); // Kurangi stok barang $barang->update([ 'stok' => $barang->stok - $request->jumlah ]); return redirect()->route('pesanan.index')->with('success', 'Pesanan berhasil dibuat'); } public function show(Pesanan $pesanan) { $pesanan->load(['user', 'barang', 'items.barang']); return view('pesanan.show', compact('pesanan')); } public function updateStatus(Request $request, Pesanan $pesanan) { $request->validate([ 'status' => 'required|in:pending,diproses,dikirim,selesai,dibatalkan' ]); $pesanan->update(['status' => $request->status]); // Jika pesanan dibatalkan, kembalikan stok if ($request->status === 'dibatalkan') { $pesanan->barang->update([ 'stok' => $pesanan->barang->stok + $pesanan->jumlah ]); } return back()->with('success', 'Status pesanan berhasil diperbarui'); } public function destroy(Pesanan $pesanan) { try { // Kembalikan stok $pesanan->barang->update([ 'stok' => $pesanan->barang->stok + $pesanan->jumlah ]); // Hapus pesanan $pesanan->delete(); return response()->json([ 'success' => true, 'message' => 'Pesanan berhasil dibatalkan' ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'Terjadi kesalahan saat membatalkan pesanan' ], 500); } } public function createFromBarang(Barang $barang) { if ($barang->stok <= 0) { return back()->with('error', 'Maaf, stok barang tidak tersedia'); } return view('pesanan.create-from-barang', compact('barang')); } public function edit(Pesanan $pesanan) { // Pastikan user hanya bisa mengedit pesanannya sendiri if ($pesanan->user_id !== Auth::id()) { return abort(403, 'Unauthorized action.'); } // Pastikan hanya pesanan dengan status pending yang bisa diedit if ($pesanan->status !== 'pending') { return redirect()->route('pesanan.index') ->with('error', 'Hanya pesanan dengan status pending yang dapat diedit'); } return view('pesanan.edit', compact('pesanan')); } public function update(Request $request, Pesanan $pesanan) { // Validasi user if ($pesanan->user_id !== Auth::id()) { return abort(403, 'Unauthorized action.'); } // Validasi status if ($pesanan->status !== 'pending') { return redirect()->route('pesanan.index') ->with('error', 'Hanya pesanan dengan status pending yang dapat diubah'); } $request->validate([ 'jumlah' => 'required|integer|min:1', 'catatan' => 'nullable|string' ]); $barang = $pesanan->barang; $stokTersedia = $barang->stok + $pesanan->jumlah; // Stok saat ini + jumlah pesanan yang akan diubah if ($request->jumlah > $stokTersedia) { return back()->with('error', 'Stok tidak mencukupi'); } // Hitung selisih stok $selisihStok = $pesanan->jumlah - $request->jumlah; // Update pesanan $pesanan->update([ 'jumlah' => $request->jumlah, 'total_harga' => $barang->harga * $request->jumlah, 'catatan' => $request->catatan ]); // Update stok barang $barang->update([ 'stok' => $barang->stok + $selisihStok ]); return redirect()->route('pesanan.index') ->with('success', 'Pesanan berhasil diperbarui'); } public function storeFromCart(Request $request) { $request->validate([ 'catatan' => 'nullable|string', 'shipping_info' => 'required|json', 'selected_items' => 'required|array' ]); $shippingInfo = json_decode($request->shipping_info, true); if (!$shippingInfo) { return redirect()->route('keranjang.index') ->with('error', 'Informasi pengiriman tidak valid'); } $query = Keranjang::with('barang')->where('user_id', Auth::id()); // Jika ada item yang dipilih, gunakan hanya item tersebut if ($request->has('selected_items') && !empty($request->selected_items)) { $query->whereIn('id', $request->selected_items); } $keranjangItems = $query->get(); if ($keranjangItems->isEmpty()) { return redirect()->route('keranjang.index') ->with('error', 'Keranjang belanja Anda kosong'); } DB::beginTransaction(); try { $totalHargaBarang = 0; $items = []; foreach ($keranjangItems as $item) { $barang = $item->barang; // Verify stock availability if ($barang->stok < $item->jumlah) { DB::rollBack(); return redirect()->route('keranjang.index') ->with('error', "Stok {$barang->nama_barang} tidak mencukupi, tersisa {$barang->stok}"); } $totalHargaBarang += $item->total_harga; $items[] = [ 'barang_id' => $barang->id, 'jumlah' => $item->jumlah, 'harga' => $barang->harga, 'subtotal' => $item->total_harga ]; // Update stock $barang->update([ 'stok' => $barang->stok - $item->jumlah ]); } // Buat satu pesanan untuk semua item $pesanan = Pesanan::create([ 'user_id' => Auth::id(), 'barang_id' => $items[0]['barang_id'], // Set barang_id dari item pertama 'jumlah' => $items[0]['jumlah'], // Set jumlah dari item pertama 'total_harga' => $totalHargaBarang + $shippingInfo['cost'], 'status' => 'pending', 'catatan' => $request->catatan, 'shipping_cost' => $shippingInfo['cost'], 'shipping_service' => $shippingInfo['service'], 'shipping_etd' => $shippingInfo['etd'], 'shipping_courier' => $shippingInfo['courier'], 'shipping_province_id' => $shippingInfo['province_id'], 'shipping_city_id' => $shippingInfo['city_id'] ]); // Simpan detail item pesanan foreach ($items as $item) { $pesanan->items()->create([ 'barang_id' => $item['barang_id'], 'jumlah' => $item['jumlah'], 'harga' => $item['harga'], 'total_harga' => $item['subtotal'] ]); } // Hapus item dari keranjang $keranjangItems->each->delete(); DB::commit(); // Buat transaksi Midtrans try { // Hitung total harga item $itemDetails = array_map(function($item) { return [ 'id' => $item['barang_id'], 'price' => $item['harga'], 'quantity' => $item['jumlah'], 'name' => $item['barang']->nama_barang ]; }, $items); // Tambahkan detail pengiriman sebagai item terpisah $itemDetails[] = [ 'id' => 'shipping', 'price' => $shippingInfo['cost'], 'quantity' => 1, 'name' => 'Ongkos Kirim - ' . strtoupper($shippingInfo['courier']) . ' ' . $shippingInfo['service'] ]; $params = [ 'transaction_details' => [ 'order_id' => 'ORDER-' . $pesanan->id, 'gross_amount' => $pesanan->total_harga, ], 'customer_details' => [ 'first_name' => Auth::user()->name, 'email' => Auth::user()->email, ], 'item_details' => $itemDetails ]; // Dapatkan Snap Token $snapToken = \Midtrans\Snap::getSnapToken($params); // Simpan transaksi $transaksi = Transaksi::create([ 'pesanan_id' => $pesanan->id, 'user_id' => Auth::id(), 'total_bayar' => $pesanan->total_harga, 'status' => 'pending', 'snap_token' => $snapToken ]); return redirect()->route('transaksi.show', $transaksi) ->with('success', 'Pesanan berhasil dibuat. Silakan selesaikan pembayaran.'); } catch (\Exception $e) { \Log::error('Midtrans Error: ' . $e->getMessage()); return redirect()->route('pesanan.index'); } } catch (\Exception $e) { DB::rollBack(); return redirect()->route('keranjang.index') ->with('error', 'Terjadi kesalahan saat membuat pesanan: ' . $e->getMessage()); } } }