diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index f7f013e..e9f8636 100644 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -252,10 +252,12 @@ class CustomerController extends Controller } } //code... + DB::commit(); return response()->json([ 'status' => true, 'data' => $order, + 'entry_at' => Carbon::now(), 'message' => 'Data berhasil disimpan' ]); } catch (\Throwable $th) { @@ -270,16 +272,29 @@ class CustomerController extends Controller public function finishCheckout(){ DB::beginTransaction(); try { + $noOrder = request('no_order_result'); $evidence = request()->file('bukti_pembayaran'); $caraPembayaran = request('cara_pembayaran'); $order = Order::where('no_order', $noOrder)->first(); // Simpan file ke storage + if (!$order) { + return response()->json(['status' => false, 'message' => 'Nomor order tidak ditemukan'], 404); + } + + $entryAt = Carbon::parse($order->entry_at)->copy()->addMinutes(10); + if(Carbon::now()->gt($entryAt)){ + return response()->json(['status' => false, 'message' => 'Waktu pembayaran sudah habis, lakukan pemesanan ulang'],403); + } + $payload = [ 'tgl_pembayaran' => Carbon::now() ]; if($caraPembayaran === "transfer"){ + if (!$evidence) { + return response()->json(['status' => false, 'message' => 'Bukti pembayaran wajib diunggah'], 422); + } $path = $evidence->store('bukti_pembayaran', 'public'); $payload['bukti_pembayaran'] = $path; $payload['cara_pembayaran'] = 'Transfer'; @@ -300,6 +315,7 @@ class CustomerController extends Controller ], 200); return back()->with('success', 'Bukti pembayaran berhasil diunggah.'); } catch (\Throwable $th) { + dd($th); DB::rollBack(); return response([ 'status' => false, diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 113afae..329f80f 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; @@ -15,6 +16,84 @@ class DashboardController extends Controller } public function dataDashboard(){ - $data = DB::connection('dbOrderGizi')->table('public.order'); + $startDate = request()->filled('start_date') + ? Carbon::parse(request('start_date'))->startOfDay() + : Carbon::now()->startOfDay(); + + $endDate = request()->filled('end_date') + ? Carbon::parse(request('end_date'))->endOfDay() + : Carbon::now()->endOfDay(); + $data = DB::connection('dbOrderGizi')->table('public.order as o') + ->leftJoin('public.order_detail as od', 'od.order_id', '=', 'o.order_id') + ->where('o.statusenabled', true) + ->whereBetween('o.entry_at', [$startDate, $endDate]) + ->select( + 'o.order_id', + 'o.entry_at', + 'o.no_order', + 'o.nama_pemesan', + 'o.jenis_customer', + 'o.total_harga', + 'o.status_order', + 'o.cara_pembayaran', + 'o.bukti_pembayaran', + 'o.note_dibatalkan', + 'od.status_order as detail_status_order') + ->get()->groupBy('order_id'); + + + + $grouped = $data->map(function($items){ + $first = $items->first(); + $totalDetail = $items->count(); + $selesaiDetail = $items->where('detail_status_order', 'Selesai')->count(); + $progress = $totalDetail > 0 ? round(($selesaiDetail / $totalDetail) * 100) : 0; + return [ + 'order_id' => $first->order_id, + 'entry_at' => $first->entry_at, + 'no_order' => $first->no_order, + 'nama_pemesan' => $first->nama_pemesan, + 'jenis_customer' => $first->jenis_customer, + 'total_harga' => $first->total_harga, + 'status_order' => $first->status_order, + 'bukti_pembayaran' => $first->bukti_pembayaran, + 'cara_pembayaran' => $first->cara_pembayaran, + 'progress' => $progress, + 'total_detail' => $totalDetail, + 'selesai_detail' => $selesaiDetail, + 'note_dibatalkan' => $first->note_dibatalkan, + ]; + })->values(); + $totalPemasukan = $grouped->sum('total_harga'); + $pesananPending = $grouped->whereNotIn('status_order', ['Lunas', 'Dibatalkan'])->count(); + $pesananLunas = $grouped->where('status_order', 'Lunas')->count(); + $pesananBatal = $grouped->where('status_order', 'Dibatalkan')->count(); + $totalPesanan = $grouped->count(); + + $pesananSelesai = DB::connection('dbOrderGizi')->table('public.order as o') + ->where('o.statusenabled', true) + ->whereBetween('o.entry_at', [$startDate, $endDate]) + ->whereNotExists(function($query){ + $query->select(DB::raw(1)) + ->from('public.order_detail as od') + ->whereColumn('od.order_id', 'o.order_id') + ->where('od.status_order', '!=', 'Selesai'); + })->count(); + + + return response()->json([ + 'status' => true, + 'message' => 'Berhasil mendapatkan data', + 'data' => [ + 'totalPesanan' => $totalPesanan, + 'totalPemasukan' => $totalPemasukan, + 'pesananPending' => $pesananPending, + 'pesananBatal' => $pesananBatal, + 'pesananLunas' => $pesananLunas, + 'pesananSelesai' => $pesananSelesai, + ], + 'rows' => $grouped->values(), + 'total' => $grouped->count(), + ],200); } } diff --git a/app/Http/Controllers/PesananController.php b/app/Http/Controllers/PesananController.php index 342597b..400cf96 100644 --- a/app/Http/Controllers/PesananController.php +++ b/app/Http/Controllers/PesananController.php @@ -32,13 +32,13 @@ class PesananController extends Controller 'o.no_order', 'o.nama_pemesan', 'o.jenis_customer', - 'o.total_harga', + 'o.cara_pembayaran', 'o.status_order', + 'o.total_harga', 'o.bukti_pembayaran', 'o.note_dibatalkan', 'od.status_order as detail_status_order' )->get()->groupBy('order_id'); - $grouped = $orders->map(function($items){ $first = $items->first(); $totalDetail = $items->count(); @@ -52,6 +52,7 @@ class PesananController extends Controller 'jenis_customer' => $first->jenis_customer, 'total_harga' => $first->total_harga, 'status_order' => $first->status_order, + 'cara_pembayaran' => $first->cara_pembayaran, 'bukti_pembayaran' => $first->bukti_pembayaran, 'progress' => $progress, 'total_detail' => $totalDetail, @@ -163,6 +164,7 @@ class PesananController extends Controller 'o.nama_pemesan', 'o.jenis_customer', 'o.total_harga', + 'o.cara_pembayaran', 'o.status_order', 'o.bukti_pembayaran', 'o.note_dibatalkan', @@ -183,6 +185,7 @@ class PesananController extends Controller 'total_harga' => $first->total_harga, 'status_order' => $first->status_order, 'bukti_pembayaran' => $first->bukti_pembayaran, + 'cara_pembayaran' => $first->cara_pembayaran, 'progress' => $progress, 'total_detail' => $totalDetail, 'selesai_detail' => $selesaiDetail, @@ -200,6 +203,21 @@ class PesananController extends Controller 'total' => $grouped->count() ]); } + + public function pekerjaan(){ + $data = [ + 'title' => 'List Pekerjaan Order Gizi' + ]; + return view('dashboard.pesanan.pekerjaan.index', $data); + } + + public function getPekerjaan(){ + $data = OrderDetail::get(); + return response()->json([ + 'rows' => $data->values(), + 'total' => $data->count() + ]); + } /** * Show the form for creating a new resource. */ diff --git a/app/Models/Order.php b/app/Models/Order.php index 4a9360b..40c8c89 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -39,7 +39,8 @@ class Order extends Model ]; protected $cast = [ - 'tgl_pembayaran' => 'datetime' + 'tgl_pembayaran' => 'datetime', + 'entry_at' => 'datetime', ]; public function orderDetail(){ diff --git a/config/app.php b/config/app.php index 423eed5..c74a68d 100644 --- a/config/app.php +++ b/config/app.php @@ -65,7 +65,7 @@ return [ | */ - 'timezone' => 'UTC', + 'timezone' => 'Asia/Jakarta', /* |-------------------------------------------------------------------------- diff --git a/public/js/checkout/action.js b/public/js/checkout/action.js index eeacf67..a4f1f0a 100644 --- a/public/js/checkout/action.js +++ b/public/js/checkout/action.js @@ -22,7 +22,9 @@ async function submitOrderToServer(){ const result = await response.json(); if (response.ok && result.status) { // Hapus sessionStorage + sessionStorage.setItem('order_id', result.data.no_order); + sessionStorage.setItem('time_order', result.entry_at); currentStep = 2; showStep(currentStep) document.getElementById('no_order_display').textContent = result.data.no_order @@ -63,7 +65,19 @@ async function submitOrderToServer(){ $("#checkoutFormFinal").on('submit', async function(e){ e.preventDefault() + const cara_pembayaran = document.getElementById('cara_pembayaran').value; + const bukti_pembayaran = document.querySelector('input[name="bukti_pembayaran"]').value; + if(cara_pembayaran === 'transfer' && !bukti_pembayaran){ + Swal.fire({ + title: 'Bukti pembayaran kosong!', + text: 'Silahkan upload bukti pembayaran jika metode yang dipakai transfer.', + icon: 'warning', + }) + return; + } + + // } const form = this; const formData = new FormData(form); @@ -78,12 +92,14 @@ async function submitOrderToServer(){ }); const result = await response.json(); + console.log(result); if (result.status) { // ✅ Hapus sessionStorage di client sessionStorage.removeItem('cart'); sessionStorage.removeItem('checkout_biodata'); sessionStorage.removeItem('order_id'); + sessionStorage.removeItem('time_order'); Swal.fire({ title: 'Pesanan Berhasil!', @@ -92,12 +108,27 @@ async function submitOrderToServer(){ confirmButtonText: 'Berhasil!', confirmButtonColor: '#28a745' }).then(() => { - window.location.href = "/success-page"; // kehalaman success + window.location.href = "/success-page"; // kehalaman success }); } else { - alert(result.message || "Terjadi kesalahan."); + sessionStorage.removeItem('cart'); + sessionStorage.removeItem('checkout_biodata'); + sessionStorage.removeItem('order_id'); + sessionStorage.removeItem('time_order'); + Swal.fire({ + title: 'Gagal!', + text: result.message, + icon: 'error', + confirmButtonText: 'Tutup!' + }).then(() => { + window.location.href = "/"; + });; } } catch (err) { + sessionStorage.removeItem('cart'); + sessionStorage.removeItem('checkout_biodata'); + sessionStorage.removeItem('order_id'); + sessionStorage.removeItem('time_order'); console.error(err); alert("Terjadi kesalahan saat mengirim data."); } diff --git a/public/js/checkout/index.js b/public/js/checkout/index.js index bd9bb87..56336d4 100644 --- a/public/js/checkout/index.js +++ b/public/js/checkout/index.js @@ -3,7 +3,6 @@ // ======================= let checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}'); let order_id = sessionStorage.getItem('order_id') || '[]'; - // ======================= // EVENT ON LOAD // ======================= @@ -11,7 +10,9 @@ document.addEventListener('DOMContentLoaded', () => { $("#cartButton").addClass('d-none'); $("#no_order_result").val(order_id) let currentStep = 0; - + let orderDate='' + let deadline='' + let time_order='' // Setup button step document.querySelectorAll('.next-step').forEach(btn => { btn.addEventListener('click', async () => { @@ -52,7 +53,13 @@ document.addEventListener('DOMContentLoaded', () => { } if (!sessionStorage.getItem('order_id')) { await submitOrderToServer(); // async function simpan ke server + } + + time_order = sessionStorage.getItem('time_order') + orderDate = new Date(time_order); + deadline = new Date(orderDate.getTime() + 10 * 60 * 1000) + updateCountdown() currentStep++; showStep(currentStep) }else if(currentStep === 2){ @@ -82,6 +89,33 @@ document.addEventListener('DOMContentLoaded', () => { toggleCustomerFields() document.getElementById('no_order_display').textContent = order_id + const countDownPayment = document.getElementById('countdownPayment') + + + + function updateCountdown(){ + const now = new Date(); + orderDate = new Date(time_order); + deadline = new Date(orderDate.getTime() + 10 * 60 * 1000) + const distance = deadline - now + + if(distance <= 0){ + countDownPayment.textContent = "Waktu Habis Lakukan Pemesanan Ulang"; + return; + } + + const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + const seconds = Math.floor((distance % (1000 * 60)) / 1000) + + countDownPayment.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` + } + + updateCountdown(); + const interval = setInterval(() => { + updateCountdown() + if(new Date() >= deadline) clearInterval(interval) + }, 1000) + }); // ======================= // FUNGSI STEP @@ -302,6 +336,9 @@ function renderCartSummary() { Menu: ${item.apakah_someday ? 'Someday' : 'Menu Normal'} +
diff --git a/resources/views/guest/checkout_order.blade.php b/resources/views/guest/checkout_order.blade.php index 87fbff8..41fd359 100644 --- a/resources/views/guest/checkout_order.blade.php +++ b/resources/views/guest/checkout_order.blade.php @@ -1,42 +1,46 @@ -