diff --git a/app/Http/Controllers/CheckoutController.php b/app/Http/Controllers/CheckoutController.php deleted file mode 100644 index 820d46e..0000000 --- a/app/Http/Controllers/CheckoutController.php +++ /dev/null @@ -1,22 +0,0 @@ -get('cart'); - if (!$cart || count($cart) == 0) { - return redirect()->route('shop')->with('error', 'Keranjang Anda kosong, silahkan belanja produk terlebih dahulu.'); - } - - return view('landing.checkout', compact('cart')); - } -} \ No newline at end of file diff --git a/app/Http/Controllers/TransaksiController.php b/app/Http/Controllers/TransaksiController.php index dcf6c38..1b2651e 100644 --- a/app/Http/Controllers/TransaksiController.php +++ b/app/Http/Controllers/TransaksiController.php @@ -3,81 +3,132 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; +use App\Models\Produk; use App\Models\Transaksi; use App\Models\DetailTransaksi; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; class TransaksiController extends Controller { - /** - * PROSES CHECKOUT / MENYIMPAN TRANSAKSI. - * Menggunakan DB Transaction agar data header dan detail tersimpan atomik (bersamaan). - */ - public function store(Request $request) + // --- FITUR PEMBELI --- + + // Tampilkan Halaman Checkout + public function checkoutPage(Request $request) { - $cart = session()->get('cart'); - - // Validasi Keranjang (Backend validation) - if (!$cart) { - return redirect()->route('shop')->with('error', 'Keranjang kosong!'); + if ($request->has('produk_id')) { + $produk = Produk::with('petani')->findOrFail($request->produk_id); + return view('landing.checkout', compact('produk')); } - // Validasi Input User + return redirect()->route('shop')->with('error', 'Silakan pilih produk yang ingin dibeli terlebih dahulu.'); + } + + // Proses Simpan Transaksi + public function prosesCheckout(Request $request) + { $request->validate([ - 'alamat_pengiriman' => 'required|string|max:500', - 'no_hp' => 'required|numeric', - 'nama_lengkap' => 'required|string|max:255', + 'produk_id' => 'required|exists:produks,id', + 'jumlah' => 'required|integer|min:1', + 'alamat_pengiriman' => 'required|string', + 'metode_pembayaran' => 'required|in:cod', ]); - try { - DB::beginTransaction(); + $produk = Produk::findOrFail($request->produk_id); - $subtotal = $this->hitungSubtotal($cart); - $ongkir = 10000; - $total_bayar = $subtotal + $ongkir; + if ($produk->stok < $request->jumlah) { + return back()->with('error', 'Stok produk tidak mencukupi!'); + } + $total_harga = $produk->harga * $request->jumlah; + + DB::transaction(function () use ($request, $produk, $total_harga) { $transaksi = Transaksi::create([ - 'pembeli_id' => Auth::guard('pembeli')->id(), + 'pembeli_id' => Auth::guard('pembeli')->id(), 'tanggal_transaksi' => now(), 'alamat_pengiriman' => $request->alamat_pengiriman, - 'total_harga' => $total_bayar, - 'status' => 'pending', - 'kode_invoice' => 'INV/' . date('Ymd') . '/' . mt_rand(1000, 9999), - 'catatan' => $request->catatan, + 'total_harga' => $total_harga, + 'status' => 'menunggu_konfirmasi', + 'kode_invoice' => 'INV/' . date('Ymd') . '/' . rand(1000, 9999), ]); - foreach ($cart as $id_produk => $details) { - DetailTransaksi::create([ - 'transaksi_id' => $transaksi->id, - 'produk_id' => $id_produk, - 'jumlah' => $details['quantity'], - 'harga_satuan' => $details['price'], - 'subtotal' => $details['price'] * $details['quantity'], - ]); - } + DetailTransaksi::create([ + 'transaksi_id' => $transaksi->id, + 'produk_id' => $produk->id, + 'jumlah' => $request->jumlah, + 'harga_satuan' => $produk->harga, + 'subtotal' => $total_harga, + ]); - DB::commit(); + // C. Kurangi Stok + $produk->decrement('stok', $request->jumlah); + }); - session()->forget('cart'); - - return redirect()->route('home')->with('success', 'Pesanan berhasil dibuat! Kode Invoice: ' . $transaksi->kode_invoice); - - } catch (\Exception $e) { - DB::rollBack(); - return redirect()->back()->with('error', 'Terjadi kesalahan saat memproses transaksi: ' . $e->getMessage()); - } + return redirect()->route('pesanan.saya')->with('success', 'Pesanan berhasil dibuat! Menunggu konfirmasi petani.'); } - /** - * Helper untuk menghitung subtotal belanjaan dari session. - */ - private function hitungSubtotal($cart) + // Riwayat Pesanan + public function pesananSaya() { - $total = 0; - foreach($cart as $id => $details) { - $total += $details['price'] * $details['quantity']; + $transaksis = Transaksi::with(['details.produk.petani']) + ->where('pembeli_id', Auth::guard('pembeli')->id()) + ->latest() + ->get(); + + return view('landing.pesanan_saya', compact('transaksis')); + } + + + // --- FITUR PETANI --- + + // Daftar Pesanan Masuk + public function pesananMasuk() + { + $petaniId = Auth::guard('petani')->id(); + + $pesanans = Transaksi::whereHas('details.produk', function ($q) use ($petaniId) { + $q->where('petani_id', $petaniId); + }) + ->with(['pembeli', 'details.produk']) + ->latest() + ->get(); + + return view('petani.pesanan.index', compact('pesanans')); + } + + // Update Status (Terima/Tolak/Kirim) + public function updateStatus(Request $request, $id) + { + $transaksi = Transaksi::findOrFail($id); + + $request->validate([ + 'status' => 'required|in:diproses,dikirim,selesai,batal' + ]); + + $transaksi->status = $request->status; + $transaksi->save(); + + if ($request->status == 'batal') { + foreach ($transaksi->details as $detail) { + $detail->produk->increment('stok', $detail->jumlah); + } } - return $total; + + return back()->with('success', 'Status pesanan berhasil diperbarui.'); + } + + // Detail Pesanan (Petani) + public function pesananDetail($id) + { + $petaniId = Auth::guard('petani')->id(); + + // Ambil transaksi berdasarkan ID, pastikan transaksi tersebut memiliki produk milik petani ini + $pesanan = Transaksi::whereHas('details.produk', function ($q) use ($petaniId) { + $q->where('petani_id', $petaniId); + }) + ->with(['pembeli', 'details.produk']) + ->findOrFail($id); + + return view('petani.pesanan.detail', compact('pesanan')); } } \ No newline at end of file diff --git a/resources/views/landing/checkout.blade.php b/resources/views/landing/checkout.blade.php index c01e478..9284bee 100644 --- a/resources/views/landing/checkout.blade.php +++ b/resources/views/landing/checkout.blade.php @@ -3,133 +3,89 @@ @section('title', 'Checkout') @section('content') - - - - -
-
-

Detail Penagihan

-
- @csrf -
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
- - -
+
+
+
+
+
+

Konfirmasi Pembelian

- -
-
- - - - - - - - - - - @php $total_belanja = 0; @endphp - @foreach($cart as $details) - @php $total = $details['price'] * $details['quantity']; $total_belanja += $total; @endphp - - - - - - - @endforeach - - - - - - - - - - - - - - - - - - -
ProdukNamaJmlTotal
-
- -
-
{{ $details['name'] }}{{ $details['quantity'] }}Rp {{ number_format($total, 0, ',', '.') }}
- -

Subtotal

-
-
-

Rp {{ number_format($total_belanja, 0, ',', '.') }}

-
-
- -

Pengiriman

-
-
- - -
-
- -

TOTAL

-
-
-

Rp {{ number_format($total_belanja + 10000, 0, ',', '.') }}

-
-
-
-
-
-
- - +
+ {{-- Form ini akan mengirim data ke TransaksiController --}} + + @csrf + + +
+
+ Produk
-
- - +
+
{{ $produk->nama_produk }}
+

Penjual: {{ $produk->petani->nama_lengkap }}

+

Rp {{ number_format($produk->harga, 0, ',', '.') }} / unit

+

{{ $produk->deskripsi }}

-
-
- -
+ +
+ +
+ + + Stok tersedia: {{ $produk->stok }} +
+ +
+ + + Pastikan alamat lengkap untuk memudahkan kurir. +
+ +
+ + +
+ +
+
Total Bayar:
+

Rp {{ number_format($produk->harga, 0, ',', '.') }}

+
+ +
+ {{-- PERBAIKAN: Gunakan button type="submit" agar form terkirim --}} + + + Batal +
+
- +
+@endsection + +@section('js') + @endsection \ No newline at end of file diff --git a/resources/views/landing/detail.blade.php b/resources/views/landing/detail.blade.php index ca5c15c..8c3af34 100644 --- a/resources/views/landing/detail.blade.php +++ b/resources/views/landing/detail.blade.php @@ -3,128 +3,142 @@ @section('title', $produk->nama_produk) @section('content') - - + + - -
-
-
-
-
-
-
- - Image - + +
+
+
+
+
+
+
+ + Image + +
-
-
-

{{ $produk->nama_produk }}

-

Kategori: {{ $produk->kategori ?? 'Sayuran' }}

-
Rp {{ number_format($produk->harga, 0, ',', '.') }} / kg
-
- - - - - +
+

{{ $produk->nama_produk }}

+

Kategori: {{ $produk->kategori ?? 'Sayuran' }}

+
Rp {{ number_format($produk->harga, 0, ',', '.') }} / kg
+
+ + + + + +
+

{{ $produk->deskripsi }}

+ + {{-- Form Add to Cart --}} +
+ @csrf + +
+
+ +
+ +
+ +
+
+ + + + Beli Sekarang + +
-

{{ $produk->deskripsi }}

- - {{-- Form Add to Cart --}} -
- @csrf - -
-
- + +
+ +
+ -
- - -
- -
- -
- - -
- - -
-
-
-
-

Produk Terkait

- {{-- looping produk lain --}} - @foreach($produk_terkait ?? [] as $related) -
-
- -
-
-
{{ $related->nama_produk }}
-
- - - - - -
-
-
Rp {{ number_format($related->harga, 0, ',', '.') }}
-
-
-
- @endforeach + +
+
+
+
+

Produk Terkait

+ @foreach ($produk_terkait ?? [] as $related) +
+
+ +
+
+
{{ $related->nama_produk }}
+
+ + + + + +
+
+
Rp + {{ number_format($related->harga, 0, ',', '.') }}
+
+
+
+ @endforeach + +
-
-@endsection \ No newline at end of file +@endsection diff --git a/resources/views/landing/home.blade.php b/resources/views/landing/home.blade.php index 0487dd7..a04efc5 100644 --- a/resources/views/landing/home.blade.php +++ b/resources/views/landing/home.blade.php @@ -3,66 +3,168 @@ @section('title', 'Beranda') @section('content') - +
-

100% Organik

-

Sayuran Segar & Buah Desa

+

100% Organik & Segar

+

Sayuran & Buah Desa
Langsung Petani

+
+
+
+
+ + + +
+
+
+
+
+
+ +
+
+
Gratis Ongkir
+

Gratis untuk radius desa

+
+
+
+
+
+
+ +
+
+
Transaksi Aman
+

Pembayaran COD Terjamin

+
+
+
+
+
+
+ +
+
+
Jaminan Kualitas
+

Garansi produk segar

+
+
+
+
+
+
+ +
+
+
Support 24/7
+

Hubungi kami kapan saja

+
- +
-

Produk Terbaru

-

Hasil panen terbaik dari petani lokal untuk meja makan Anda.

+

Produk Panen Terbaru

+

Pilihan hasil bumi terbaik yang baru saja dipanen oleh petani lokal.

@forelse($produks as $produk)
- + {{ $produk->nama_produk }}
Segar
-

{{ $produk->nama_produk }}

-

{{ Str::limit($produk->deskripsi, 50) }}

+
{{ $produk->nama_produk }}
+

{{ Str::limit($produk->deskripsi, 45) }}

-

Rp {{ number_format($produk->harga, 0, ',', '.') }}

- Detail +

Rp {{ number_format($produk->harga, 0, ',', '.') }} / kg

+ + Detail +
@empty -
-
Belum ada produk yang tersedia.
+
+
+ Belum ada produk yang dijual saat ini. +
@endforelse
+ + +
+
+ + + @endsection \ No newline at end of file diff --git a/resources/views/landing/pesanan_saya.blade.php b/resources/views/landing/pesanan_saya.blade.php new file mode 100644 index 0000000..edea5c1 --- /dev/null +++ b/resources/views/landing/pesanan_saya.blade.php @@ -0,0 +1,80 @@ + +@extends('layouts.frontend') + +@section('title', 'Pesanan Saya') + +@section('content') +
+

Riwayat Pesanan

+ + @if(session('success')) + + @endif + +
+
+ @if($transaksis->isEmpty()) +
+ +

Belum ada pesanan.

+ Mulai Belanja +
+ @else +
+ + + + + + + + + + + + + @foreach($transaksis as $trx) + + + + + + + + + @endforeach + +
InvoiceTanggalProdukTotalStatusAksi
#{{ $trx->kode_invoice }}{{ \Carbon\Carbon::parse($trx->tanggal_transaksi)->format('d M Y') }} + @foreach($trx->details as $detail) +
+ +
+ {{ $detail->produk->nama_produk }} + {{ $detail->jumlah }} x Rp {{ number_format($detail->harga_satuan, 0, ',', '.') }} +
+
+ @endforeach +
Rp {{ number_format($trx->total_harga, 0, ',', '.') }} + @if($trx->status == 'menunggu_konfirmasi') + Menunggu Konfirmasi + @elseif($trx->status == 'diproses') + Sedang Diproses + @elseif($trx->status == 'dikirim') + Sedang Dikirim + @elseif($trx->status == 'selesai') + Selesai + @else + Dibatalkan + @endif + + Detail +
+
+ @endif +
+
+
+@endsection \ No newline at end of file diff --git a/resources/views/landing/shop.blade.php b/resources/views/landing/shop.blade.php index 4c3fb3f..c717547 100644 --- a/resources/views/landing/shop.blade.php +++ b/resources/views/landing/shop.blade.php @@ -3,78 +3,90 @@ @section('title', 'Belanja Sayur') @section('content') - - + + - -
-
-
-
- -
-
-
- @forelse($produks as $produk) -
-
-
-
    -
  • - -
  • -
  • - -
  • -
-
-
-
{{ $produk->nama_produk }}
-
Rp {{ number_format($produk->harga, 0, ',', '.') }}
+ +
+
+

Toko Sayur & Buah Segar

+
+
+
+ +
+
+
+ + +
+
+ +
+
+
+

Kategori

+ +
- @empty -
-
Produk tidak ditemukan.
-
- @endforelse -
- - -
-
- {{ $produks->links() }} + + +
+
+ @forelse($produks as $produk) +
+
+
+ {{ $produk->nama_produk }} +
+
Segar
+
+

{{ $produk->nama_produk }}

+

{{ Str::limit($produk->deskripsi, 50) }}

+
+

Rp {{ number_format($produk->harga, 0, ',', '.') }} / kg

+ Detail +
+
+
+
+ @empty +
+
+ +

Produk tidak ditemukan

+

Coba kata kunci lain atau kembali lagi nanti.

+ Reset Pencarian +
+
+ @endforelse + + +
+
+ {{ $produks->links() }} +
+
+
-
+
@endsection \ No newline at end of file diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php index b72bb9a..b0a0925 100644 --- a/resources/views/layouts/admin.blade.php +++ b/resources/views/layouts/admin.blade.php @@ -6,12 +6,13 @@ @yield('title') - TaniDesa - + - + @yield('css') @@ -19,7 +20,7 @@ - +
- +
- - + @yield('js') - \ No newline at end of file + + diff --git a/resources/views/layouts/frontend.blade.php b/resources/views/layouts/frontend.blade.php index 8ce7d89..89abfb2 100644 --- a/resources/views/layouts/frontend.blade.php +++ b/resources/views/layouts/frontend.blade.php @@ -1,160 +1,234 @@ - - - @yield('title') - TaniDesa - - - - - - + + + @yield('title') - TaniDesa + - - - + + + - - + + + + - - + + - - - - @yield('css') - + @yield('css') + - + - -
-
-
- + +
+
+
+ + +
+
+ -
- -
-
- - -