377 lines
12 KiB
PHP
377 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Pesanan;
|
|
use App\Models\Barang;
|
|
use App\Models\Keranjang;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
|
use App\Models\Transaksi;
|
|
|
|
class PesananController extends Controller
|
|
{
|
|
use AuthorizesRequests;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->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());
|
|
}
|
|
}
|
|
}
|