From d2e6f70bf622537da1e6cf4600d66bb7bd0049a2 Mon Sep 17 00:00:00 2001 From: pand03-CEO Date: Fri, 31 Jul 2026 08:09:50 +0700 Subject: [PATCH] Melengkapi laporan semua transaksi --- app/Http/Controllers/LevelMenuController.php | 84 ++ .../Parking/ReportTransaksiController.php | 897 ++++++++++--- .../Setup/UserLevel/LevelMenuController.php | 85 ++ .../Setup/UserLevel/LevelUserController.php | 2 +- .../ModifiedVehiclepriceController.php | 8 +- ...rkingSetupUserLevelLevelMenuController.php | 84 ++ public/js/report/report-vehicle.js | 1173 +++++++++++++++++ resources/views/report/all-report.blade.php | 402 +----- .../report/stiker/stiker-harian.blade.php | 60 +- .../setup/UserLevel/level-user-menu.blade.php | 30 + .../setup/UserLevel/level-user.blade.php | 109 +- routes/web.php | 7 +- 12 files changed, 2252 insertions(+), 689 deletions(-) create mode 100644 app/Http/Controllers/LevelMenuController.php create mode 100644 app/Http/Controllers/Parking/Setup/UserLevel/LevelMenuController.php create mode 100644 app/Http/Controllers/ParkingSetupUserLevelLevelMenuController.php create mode 100644 public/js/report/report-vehicle.js create mode 100644 resources/views/setup/UserLevel/level-user-menu.blade.php diff --git a/app/Http/Controllers/LevelMenuController.php b/app/Http/Controllers/LevelMenuController.php new file mode 100644 index 0000000..0227cd2 --- /dev/null +++ b/app/Http/Controllers/LevelMenuController.php @@ -0,0 +1,84 @@ +all()); - $awal = $request->tanggal_mulai; - $akhir = $request->tanggal_selesai; - $isShift = $request->shift === 'on'; - $dateBy = $isShift ? 'pklogin' : 'waktu_keluar'; - $paymentMethod = $request->payment_method === 'null' ? null : $request->payment_method; + $awal = $request->tanggal_mulai; + $akhir = $request->tanggal_selesai; + $isShift = $request->shift === "on"; + $dateBy = $isShift ? "pklogin" : "waktu_keluar"; + $paymentMethod = $request->payment_method === "null" ? null : $request->payment_method; // ๐Ÿ”น Base select $select = [ - 'np.nama as gate', - 'tp.id_pintu_keluar', - 'p.nama as petugas', - 'tp.id_op_keluar', - 'jm.nama as kendaraan', - 'tp.status_transaksi', - DB::raw('count(*) as jumlah_transaksi'), - DB::raw('sum(tp.bayar_keluar) as income_transaksi'), + "np.nama as gate", + "tp.id_pintu_keluar", + "p.nama as petugas", + "tp.id_op_keluar", + "jm.nama as kendaraan", + "tp.status_transaksi", + DB::raw("count(*) as jumlah_transaksi"), + DB::raw("sum(tp.bayar_keluar) as income_transaksi"), ]; // ๐Ÿ”น Tambah shift kalau aktif if ($isShift) { - $select[] = 'tp.id_shift_keluar'; + $select[] = "tp.id_shift_keluar"; } // ๐Ÿ”น Base group - $groupBy = [ - 'tp.id_pintu_keluar', - 'np.nama', - 'p.nama', - 'tp.id_op_keluar', - 'jm.nama', - 'tp.status_transaksi', - ]; + $groupBy = ["tp.id_pintu_keluar", "np.nama", "p.nama", "tp.id_op_keluar", "jm.nama", "tp.status_transaksi"]; if ($isShift) { - $groupBy[] = 'tp.id_shift_keluar'; + $groupBy[] = "tp.id_shift_keluar"; } - $query = DB::table('transaksi_parkir as tp') - ->leftJoin('pegawai as p','p.nomer','=','tp.id_op_keluar') - ->leftJoin('nama_pos as np','np.id','=','tp.id_pintu_keluar') - ->leftJoin('jenis_mobil as jm','jm.id','=','tp.id_kendaraan') + $query = DB::table("transaksi_parkir as tp") + ->leftJoin("pegawai as p", "p.nomer", "=", "tp.id_op_keluar") + ->leftJoin("nama_pos as np", "np.id", "=", "tp.id_pintu_keluar") + ->leftJoin("jenis_mobil as jm", "jm.id", "=", "tp.id_kendaraan") ->select($select) // ๐Ÿ”น Filter tanggal (dynamic field) - ->where('tp.status', 0) + ->where("tp.status", 0) - ->whereBetween($dateBy, [ - $awal . ' 00:00:00', - $akhir . ' 23:59:59' - ]) + ->whereBetween($dateBy, [$awal . " 00:00:00", $akhir . " 23:59:59"]) // // ๐Ÿ”น STATUS // ->when($request->status_transaksi, fn($q, $v) => @@ -77,37 +75,31 @@ public function gateData(Request $request) // ) // ๐Ÿ”น PINTU - ->when($request->id_pintu_keluar, fn($q, $v) => - $q->whereIn('tp.id_pintu_keluar', (array) $v) - ) + ->when($request->id_pintu_keluar, fn($q, $v) => $q->whereIn("tp.id_pintu_keluar", (array) $v)) // ๐Ÿ”น Status Transaksi // ->when($request->status_transaksi, function ($q) use ($request) { ->when(isset($request->status_transaksi), function ($q) use ($request) { - return match ($request->status_transaksi) { // '0' => $q->whereNotIn('tp.status_transaksi', ['3','-1'])->whereNotNull('alasan'), - '0' => $q->where('tp.status_transaksi', '0')->whereNull('alasan'), - '3' => $q->where('tp.status_transaksi', '3')->whereNull('alasan'), - '-1' => $q->where('tp.status_transaksi', '-1')->whereNotNull('alasan'), - 'null' => $q->whereNull('alasan') + "0" => $q->where("tp.status_transaksi", "0")->whereNull("alasan"), + "3" => $q->where("tp.status_transaksi", "3")->whereNull("alasan"), + "-1" => $q->where("tp.status_transaksi", "-1")->whereNotNull("alasan"), + "null" => $q->whereNull("alasan"), }; - }) // ๐Ÿ”น CARA BAYAR ->when($request->cara_bayar, function ($q) use ($request) { - return match ($request->cara_bayar) { - 'cash' => $q->where('tp.cara_bayar', '!=', 3), - 'cashless' => $q->where('tp.cara_bayar', 3), - default => $q + "cash" => $q->where("tp.cara_bayar", "!=", 3), + "cashless" => $q->where("tp.cara_bayar", 3), + default => $q, }; - }) ->when($paymentMethod, function ($q) use ($paymentMethod) { - return $q->where('tp.rep_bank', $paymentMethod); + return $q->where("tp.rep_bank", $paymentMethod); // return match ($request->payment_method) { // 2 => $q->where('tp.rep_bank', 2), @@ -117,11 +109,8 @@ public function gateData(Request $request) // 9 => $q->where('tp.rep_bank', 9), // default => $q // }; - }) - - // // ๐Ÿ”น PETUGAS // ->when($request->id_op_keluar, fn($q, $v) => // $q->whereIn('tp.id_op_keluar', (array) $v) @@ -134,121 +123,120 @@ public function gateData(Request $request) ->groupBy($groupBy) - ->orderBy('tp.id_pintu_keluar') - ->when($isShift, fn($q) => - $q->orderBy('tp.id_shift_keluar') - ) - ->orderBy('tp.id_op_keluar') - ->orderBy('jm.nama') - ->orderBy('tp.status_transaksi'); - + ->orderBy("tp.id_pintu_keluar") + ->when($isShift, fn($q) => $q->orderBy("tp.id_shift_keluar")) + ->orderBy("tp.id_op_keluar") + ->orderBy("jm.nama") + ->orderBy("tp.status_transaksi"); return response()->json([ - 'byGateData' => $query->get() + "byGateData" => $query->get(), ]); } - public function allReport () + public function allReport() { - return view ('report.all-report'); + return view("report.all-report"); } public function allReportData(Request $request) { - Log::info('== allReportData START =='); + return response()->json([ + "vehicle" => $this->vehicleReport($request), + "officer" => $this->reportOfficer($request), + "payment" => $this->paymentType($request), + ]); + } + public function vehicleReport(Request $request) + { + Log::info("== allReportData START =="); Log::info($request->harian); Log::info($request->tanggal); $selectDate = $request->tanggal; $start = microtime(true); $harian = $request->harian ?? 1; - // $dateNow = Carbon::now()->format('Y-m-d'); - $dateNow = '2026-01-25'; - // $startDate = Carbon::today()->startOfDay(); - // $endDate = Carbon::today()->endOfDay(); - // $startDate = $selectDate . ' 00:00:00'; - // $endDate = $selectDate . ' 23:59:59'; + $dateNow = "2026-01-25"; $startDate = $selectDate ? $selectDate : $dateNow; - $endDate = $selectDate ? $selectDate : $dateNow; + $endDate = $selectDate ? $selectDate : $dateNow; - Log::info('Tanggal laporan', [ - 'start' => $startDate, - 'end' => $endDate + Log::info("Tanggal laporan", [ + "start" => $startDate, + "end" => $endDate, ]); // ========================= // QUERY UTAMA (LEFT JOIN) // ========================= - Log::info('Query transaksi dimulai'); + Log::info("Query transaksi dimulai"); // $dateColumn = $harian == 1 // ? 'tp.waktu_keluar' // : 'tp.pklogin'; if ($harian == 1) { // $dateColumn = ['tp.waktu_masuk', 'tp.waktu_keluar']; - $dateColumn = ['tp.waktu_keluar']; + $dateColumn = ["tp.waktu_keluar"]; } else { // $dateColumn = ['tp.pmlogin', 'tp.pklogin']; - $dateColumn = ['tp.pklogin']; + $dateColumn = ["tp.pklogin"]; } - $transactions = DB::table('transaksi_parkir as tp') - ->leftJoin('jenis_mobil as jm', 'jm.id', '=', 'tp.id_kendaraan') - ->leftJoin('pegawai as pm', 'pm.nomer', '=', 'tp.id_op_masuk') - ->leftJoin('pegawai as pk', 'pk.nomer', '=', 'tp.id_op_keluar') + $transactions = DB::table("transaksi_parkir as tp") + ->leftJoin("jenis_mobil as jm", "jm.id", "=", "tp.id_kendaraan") + ->leftJoin("pegawai as pm", "pm.nomer", "=", "tp.id_op_masuk") + ->leftJoin("pegawai as pk", "pk.nomer", "=", "tp.id_op_keluar") ->where(function ($q) use ($dateColumn, $startDate, $endDate, $selectDate) { - $q->whereBetween($dateColumn[0], [$startDate . ' 00:00:00', $endDate . ' 23:59:59']) - ->orWhereBetween($dateColumn[0], [$startDate . ' 00:00:00', $endDate . ' 23:59:59']); + $q->whereBetween($dateColumn[0], [$startDate . " 00:00:00", $endDate . " 23:59:59"])->orWhereBetween( + $dateColumn[0], + [$startDate . " 00:00:00", $endDate . " 23:59:59"], + ); // $q->whereRaw('DATE(tp.waktu_masuk) = ?', [$selectDate]) // ->orWhereRaw('DATE(tp.waktu_keluar) = ?', [$selectDate]); }) // ->whereRaw("DATE($dateColumn) = ?", [$dateNow]) // ->whereBetween($dateColumn, [$startDate, $endDate]) ->select( - 'tp.id', - 'jm.nama as jenis_mobil', - 'tp.id_kendaraan', + "tp.id", + "jm.nama as jenis_mobil", + "tp.id_kendaraan", - 'pm.nama as kasir_masuk', - 'pk.nama as kasir_keluar', + "pm.nama as kasir_masuk", + "pk.nama as kasir_keluar", - 'tp.id_op_masuk', + "tp.id_op_masuk", - 'tp.waktu_masuk', - 'tp.waktu_keluar', - 'tp.status', - 'tp.bayar_masuk', - 'tp.bayar_keluar', - 'tp.status_transaksi', - 'tp.cara_bayar', + "tp.waktu_masuk", + "tp.waktu_keluar", + "tp.status", + "tp.bayar_masuk", + "tp.bayar_keluar", + "tp.status_transaksi", + "tp.cara_bayar", ) ->get(); - Log::info('Query transaksi selesai', [ - 'rows' => $transactions->count(), - 'query_time_ms' => round((microtime(true) - $start) * 1000, 2) + Log::info("Query transaksi selesai", [ + "rows" => $transactions->count(), + "query_time_ms" => round((microtime(true) - $start) * 1000, 2), ]); // ========================= // REKAP PER KENDARAAN // ========================= - Log::info('Rekap kendaraan dimulai'); + Log::info("Rekap kendaraan dimulai"); $tunai = $transactions - ->sortBy('id_kendaraan') - ->groupBy('id_kendaraan') + ->sortBy("id_kendaraan") + ->groupBy("id_kendaraan") ->map(function ($items, $idKendaraan) { - // ====================== // PISAH MASUK & KELUAR // ====================== // $masuk = $items->where('status', 1); // $keluar = $items->where('status', 0); - $keluar = $items->filter(fn ($r) => (int) $r->status === 0); + $keluar = $items->filter(fn($r) => (int) $r->status === 0); // $tunai = $keluar->where('cara_bayar', '!=', 3); - $tunai = $keluar->filter(fn ($row) => - in_array(data_get($row, 'cara_bayar'), [null, 0, '0'], true) - ); + $tunai = $keluar->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true)); // ====================== // MASUK @@ -262,32 +250,34 @@ public function allReportData(Request $request) // $keluarCasual = $tunai->where('status_transaksi', '0'); // $keluarMember = $tunai->where('status_transaksi', '3'); // $keluarLost = $tunai->where('status_transaksi', '32'); - $keluarCasual = $tunai->filter(fn ($r) => - (string) data_get($r, 'status_transaksi') === '0' - && data_get($r, 'id_op_masuk') !== null + $keluarCasual = $tunai->filter( + fn($r) => (string) data_get($r, "status_transaksi") === "0" && data_get($r, "id_op_masuk") !== null, ); - $keluarMember = $tunai->filter(fn ($r) => (string) data_get($r, 'status_transaksi') === '3'); + $keluarMember = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "3"); - $keluarLost = $tunai->filter(fn ($r) => (string) data_get($r, 'status_transaksi') === '32'); + $keluarLost = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "32"); - $keluarManual = $tunai->filter(fn ($r) => data_get($r, 'id_op_masuk') === null); + $keluarManual = $tunai->filter(fn($r) => data_get($r, "id_op_masuk") === null); - $keluarMasalah = $tunai->filter(fn ($r) => (string) data_get($r, 'status_transaksi') === '-1'); + $keluarMasalah = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "-1"); // ====================== // PEMBAYARAN (KELUAR) // ====================== // $nonTunai = $keluar->where('cara_bayar', 3); // $tunai = $keluar->where('cara_bayar', '!=', 3); - $totalCash = $keluarCasual->sum('bayar_keluar') + $keluarLost->sum('bayar_keluar') + $keluarMember->sum('bayar_keluar') + $keluarManual->sum('bayar_keluar'); - + $totalCash = + $keluarCasual->sum("bayar_keluar") + + $keluarLost->sum("bayar_keluar") + + $keluarMember->sum("bayar_keluar") + + $keluarManual->sum("bayar_keluar"); return [ - 'id_kendaraan' => $idKendaraan, - 'jenis_mobil' => $items->first()->jenis_mobil, - 'total' => $items->count(), - 'tunaiOut' => $tunai->count(), + "id_kendaraan" => $idKendaraan, + "jenis_mobil" => $items->first()->jenis_mobil, + "total" => $items->count(), + "tunaiOut" => $tunai->count(), // ========= MASUK ========= // 'masuk' => [ // 'casual' => [ @@ -301,49 +291,46 @@ public function allReportData(Request $request) // ], // ========= KELUAR ========= - 'keluar' => [ - 'casual' => [ - 'jumlah' => $keluarCasual->count(), - 'income' => $keluarCasual->sum('bayar_keluar'), + "keluar" => [ + "casual" => [ + "jumlah" => $keluarCasual->count(), + "income" => $keluarCasual->sum("bayar_keluar"), ], - 'lost' => [ - 'jumlah' => $keluarLost->count(), - 'income' => $keluarLost->sum('bayar_keluar'), + "lost" => [ + "jumlah" => $keluarLost->count(), + "income" => $keluarLost->sum("bayar_keluar"), ], - 'member' => [ - 'jumlah' => $keluarMember->count(), - 'income' => $keluarMember->sum('bayar_keluar'), + "member" => [ + "jumlah" => $keluarMember->count(), + "income" => $keluarMember->sum("bayar_keluar"), ], - 'manual' => [ - 'jumlah' => $keluarManual->count(), - 'income' => $keluarManual->sum('bayar_keluar'), + "manual" => [ + "jumlah" => $keluarManual->count(), + "income" => $keluarManual->sum("bayar_keluar"), ], - 'masalah' => [ - 'jumlah' => $keluarMasalah->count(), - 'income' => $keluarMasalah->sum('bayar_keluar'), + "masalah" => [ + "jumlah" => $keluarMasalah->count(), + "income" => $keluarMasalah->sum("bayar_keluar"), ], ], - 'totalCash' => $totalCash, + "totalCash" => $totalCash, ]; - } - )->values(); + }) + ->values(); $cashless = $transactions - ->sortBy('id_kendaraan') - ->groupBy('id_kendaraan') + ->sortBy("id_kendaraan") + ->groupBy("id_kendaraan") ->map(function ($items, $idKendaraan) { - // ====================== // PISAH MASUK & KELUAR // ====================== // $masuk = $items->where('status', 1); // $keluar = $items->where('status', 0); // $nonTunai = $keluar->where('cara_bayar', 3); - $keluar = $items->filter(fn ($r) => (int) $r->status === 0); + $keluar = $items->filter(fn($r) => (int) $r->status === 0); // $tunai = $keluar->where('cara_bayar', '!=', 3); - $nonTunai = $keluar->filter(fn ($row) => - (string) data_get($row, 'cara_bayar') === '3' - ); + $nonTunai = $keluar->filter(fn($row) => (string) data_get($row, "cara_bayar") === "3"); // ====================== // MASUK @@ -357,25 +344,28 @@ public function allReportData(Request $request) // $keluarCasual = $nonTunai->where('status_transaksi', '0'); // $keluarMember = $nonTunai->where('status_transaksi', '3'); // $keluarLost = $nonTunai->where('status_transaksi', '32'); - $keluarCasual = $nonTunai->filter(fn ($r) => - (string) data_get($r, 'status_transaksi') === '0' - && data_get($r, 'id_op_masuk') !== null + $keluarCasual = $nonTunai->filter( + fn($r) => (string) data_get($r, "status_transaksi") === "0" && data_get($r, "id_op_masuk") !== null, ); - $keluarMember = $nonTunai->filter(fn ($r) => (string) data_get($r, 'status_transaksi') === '3'); - $keluarLost = $nonTunai->filter(fn ($r) => (string) data_get($r, 'status_transaksi') === '32'); - $keluarManual = $nonTunai->filter(fn ($r) => data_get($r, 'id_op_masuk') === null); + $keluarMember = $nonTunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "3"); + $keluarLost = $nonTunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "32"); + $keluarManual = $nonTunai->filter(fn($r) => data_get($r, "id_op_masuk") === null); - $totalCashless = $keluarCasual->sum('bayar_keluar') + $keluarLost->sum('bayar_keluar') + $keluarMember->sum('bayar_keluar') + $keluarManual->sum('bayar_keluar'); + $totalCashless = + $keluarCasual->sum("bayar_keluar") + + $keluarLost->sum("bayar_keluar") + + $keluarMember->sum("bayar_keluar") + + $keluarManual->sum("bayar_keluar"); // ====================== // PEMBAYARAN (KELUAR) // ====================== return [ - 'id_kendaraan' => $idKendaraan, - 'jenis_mobil' => $items->first()->jenis_mobil, - 'total' => $items->count(), - 'nonTunaiOut' => $nonTunai->count(), + "id_kendaraan" => $idKendaraan, + "jenis_mobil" => $items->first()->jenis_mobil, + "total" => $items->count(), + "nonTunaiOut" => $nonTunai->count(), // ========= MASUK ========= // 'masuk' => [ @@ -390,81 +380,582 @@ public function allReportData(Request $request) // ], // ========= KELUAR ========= - 'keluar' => [ - 'casual' => [ - 'jumlah' => $keluarCasual->count(), - 'income' => $keluarCasual->sum('bayar_keluar'), + "keluar" => [ + "casual" => [ + "jumlah" => $keluarCasual->count(), + "income" => $keluarCasual->sum("bayar_keluar"), ], - 'lost' => [ - 'jumlah' => $keluarLost->count(), - 'income' => $keluarLost->sum('bayar_keluar'), + "lost" => [ + "jumlah" => $keluarLost->count(), + "income" => $keluarLost->sum("bayar_keluar"), ], - 'member' => [ - 'jumlah' => $keluarMember->count(), - 'income' => $keluarMember->sum('bayar_keluar'), + "member" => [ + "jumlah" => $keluarMember->count(), + "income" => $keluarMember->sum("bayar_keluar"), ], - 'manual' => [ - 'jumlah' => $keluarManual->count(), - 'income' => $keluarManual->sum('bayar_keluar'), + "manual" => [ + "jumlah" => $keluarManual->count(), + "income" => $keluarManual->sum("bayar_keluar"), ], ], - 'totalCashless' => $totalCashless, + "totalCashless" => $totalCashless, ]; - } - )->values(); + }) + ->values(); - $transactions = DB::table('transaksi_parkir as tp') - ->leftJoin('jenis_mobil as jm', 'jm.id', '=', 'tp.id_kendaraan') - ->leftJoin('pegawai as pm', 'pm.nomer', '=', 'tp.id_op_masuk') - ->leftJoin('pegawai as pk', 'pk.nomer', '=', 'tp.id_op_keluar') - ->whereDate('waktu_masuk', '<', $dateNow) + $transactions = DB::table("transaksi_parkir as tp") + ->leftJoin("jenis_mobil as jm", "jm.id", "=", "tp.id_kendaraan") + ->leftJoin("pegawai as pm", "pm.nomer", "=", "tp.id_op_masuk") + ->leftJoin("pegawai as pk", "pk.nomer", "=", "tp.id_op_keluar") + ->whereDate("waktu_masuk", "<", $dateNow) ->select( - 'tp.id_kendaraan', - 'jm.nama as jenis_mobil', + "tp.id_kendaraan", + "jm.nama as jenis_mobil", DB::raw("SUM(CASE WHEN tp.status = 1 THEN 1 ELSE 0 END) as overnight"), - DB::raw("SUM(CASE WHEN tp.status = 3 THEN 1 ELSE 0 END) as onexpired") + DB::raw("SUM(CASE WHEN tp.status = 3 THEN 1 ELSE 0 END) as onexpired"), ) - ->groupBy('tp.id_kendaraan', 'jm.nama') - ->orderBy('tp.id_kendaraan') + ->groupBy("tp.id_kendaraan", "jm.nama") + ->orderBy("tp.id_kendaraan") // dd($transactions->toSql()); ->get(); - $onCheck = $transactions // ->sortBy('id_kendaraan') // ->groupBy('id_kendaraan') ->map(function ($items) { - // $overNight = $items->filter(fn ($r) => (int) $r->status === 1); // $onExpired = $items->filter(fn ($r) => (int) $r->status === 3); return [ - 'id_kendaraan' => $items->id_kendaraan, - 'jenis_mobil' => $items->jenis_mobil, - 'overNight' => (int) $items->overnight, - 'onExpired' => (int) $items->onexpired, + "id_kendaraan" => $items->id_kendaraan, + "jenis_mobil" => $items->jenis_mobil, + "overNight" => (int) $items->overnight, + "onExpired" => (int) $items->onexpired, ]; - } - )->values(); + }) + ->values(); - Log::info('Rekap kendaraan selesai', [ - 'total_kendaraan' => $tunai->count() + Log::info("Rekap kendaraan selesai", [ + "total_kendaraan" => $tunai->count(), ]); - Log::info('== allReportData END ==', [ - 'total_time_ms' => round((microtime(true) - $start) * 1000, 2) + Log::info("== allReportData END ==", [ + "total_time_ms" => round((microtime(true) - $start) * 1000, 2), ]); - - - return response()->json([ + return [ // 'date' => $startDate->format('Y-m-d'),รท - 'date' => $startDate, - 'tunai' => $tunai, - 'nontunai' => $cashless, - 'overNight' => $onCheck + "date" => $startDate, + "tunai" => $tunai, + "nontunai" => $cashless, + "overNight" => $onCheck, // 'transactions' => $transactions->groupBy('id_kendaraan') - ]); + ]; } + // ==========###################### Begin Laporan per petugas #######################===============// + public function reportOfficer(Request $request) + { + Log::info("== Officer Report START =="); + Log::info($request->harian); + Log::info($request->tanggal); + $selectDate = $request->tanggal; + $start = microtime(true); + $harian = $request->harian ?? 1; + // $selectDate = Carbon::createFromFormat("", $tanggalRequest)->format("Y-m-d"); + // $dateNow = Carbon::now()->format('Y-m-d'); + $dateNow = "2026-01-25"; + // $startDate = Carbon::today()->startOfDay(); + // $endDate = Carbon::today()->endOfDay(); + // $startDate = $selectDate . ' 00:00:00'; + // $endDate = $selectDate . ' 23:59:59'; + $startDate = $selectDate ? $selectDate : $dateNow; + $endDate = $selectDate ? $selectDate : $dateNow; + + Log::info("Tanggal laporan", [ + "start" => $startDate, + "end" => $endDate, + ]); + + // ========================= + // QUERY UTAMA (LEFT JOIN) + // ========================= + Log::info("Query transaksi dimulai"); + + // $dateColumn = $harian == 1 + // ? 'tp.waktu_keluar' + // : 'tp.pklogin'; + if ($harian == 1) { + // $dateColumn = ['tp.waktu_masuk', 'tp.waktu_keluar']; + $dateColumn = ["tp.waktu_keluar"]; + } else { + // $dateColumn = ['tp.pmlogin', 'tp.pklogin']; + $dateColumn = ["tp.pklogin"]; + } + + $transactions = DB::table("transaksi_parkir as tp") + ->leftJoin("pegawai as p", "p.nomer", "=", "tp.id_op_keluar") + // ->leftJoin("pegawai as pm", "pm.nomer", "=", "tp.id_op_masuk") + // ->leftJoin("pegawai as pk", "pk.nomer", "=", "tp.id_op_keluar") + ->where(function ($q) use ($dateColumn, $startDate, $endDate, $selectDate) { + $q->whereBetween($dateColumn[0], [$startDate . " 00:00:00", $endDate . " 23:59:59"])->orWhereBetween( + $dateColumn[0], + [$startDate . " 00:00:00", $endDate . " 23:59:59"], + ); + // $q->whereRaw('DATE(tp.waktu_masuk) = ?', [$selectDate]) + // ->orWhereRaw('DATE(tp.waktu_keluar) = ?', [$selectDate]); + }) + // ->whereRaw("DATE($dateColumn) = ?", [$dateNow]) + // ->whereBetween($dateColumn, [$startDate, $endDate]) + ->select( + "p.nomer as id_petugas", + "p.nama as petugas", + // "tp.id_kendaraan", + + // "pm.nama as kasir_masuk", + // "pk.nama as kasir_keluar", + "tp.id_op_masuk", // โœ… ADA + "tp.id_op_keluar", + + "tp.waktu_masuk", + "tp.waktu_keluar", + "tp.status", + "tp.bayar_masuk", + "tp.bayar_keluar", + "tp.status_transaksi", + "tp.cara_bayar", + ) + ->get(); + // Log::info("Result nya : " . json_encode($transactions)); + + Log::info("Query transaksi selesai", [ + "rows" => $transactions->count(), + "query_time_ms" => round((microtime(true) - $start) * 1000, 2), + ]); + + // ========================= + // REKAP PER KENDARAAN + // ========================= + Log::info("Rekap petugas dimulai"); + + $tunai = $transactions + ->sortBy("id_op_keluar") + ->groupBy("id_op_keluar") + ->map(function ($items, $id_op_keluar) { + // ====================== + // PISAH MASUK & KELUAR + // ====================== + // $masuk = $items->where('status', 1); + // $keluar = $items->where('status', 0); + $keluar = $items->filter(fn($r) => (int) $r->status === 0); + // $tunai = $keluar->where('cara_bayar', '!=', 3); + $tunai = $keluar->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true)); + + // ====================== + // MASUK + // ====================== + // $masukCasual = $masuk->where('status_transaksi', '0'); + // $masukMember = $masuk->where('status_transaksi', '3'); + + // ====================== + // KELUAR + // ====================== + // $keluarCasual = $tunai->where('status_transaksi', '0'); + // $keluarMember = $tunai->where('status_transaksi', '3'); + // $keluarLost = $tunai->where('status_transaksi', '32'); + $keluarCasual = $tunai->filter( + fn($r) => (string) data_get($r, "status_transaksi") === "0" && data_get($r, "id_op_masuk") !== null, + ); + + $keluarMember = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "3"); + + $keluarLost = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "32"); + + $keluarManual = $tunai->filter(fn($r) => data_get($r, "id_op_masuk") === null); + + $keluarMasalah = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "-1"); + + // ====================== + // PEMBAYARAN (KELUAR) + // ====================== + // $nonTunai = $keluar->where('cara_bayar', 3); + // $tunai = $keluar->where('cara_bayar', '!=', 3); + $totalCash = + $keluarCasual->sum("bayar_keluar") + + $keluarLost->sum("bayar_keluar") + + $keluarMember->sum("bayar_keluar") + + $keluarManual->sum("bayar_keluar"); + + Log::info("Transaksi tunai : "); + + return [ + "id_petugas" => $id_op_keluar, + "petugas" => $items->first()->petugas, + "total" => $items->count(), + "tunaiOut" => $tunai->count(), + // ========= MASUK ========= + // 'masuk' => [ + // 'casual' => [ + // 'jumlah' => $masukCasual->count(), + // 'income' => $masukCasual->sum('bayar_masuk'), + // ], + // 'member' => [ + // 'jumlah' => $masukMember->count(), + // 'income' => $masukMember->sum('bayar_masuk'), + // ], + // ], + + // ========= KELUAR ========= + "keluar" => [ + "casual" => [ + "jumlah" => $keluarCasual->count(), + "income" => $keluarCasual->sum("bayar_keluar"), + ], + "lost" => [ + "jumlah" => $keluarLost->count(), + "income" => $keluarLost->sum("bayar_keluar"), + ], + "member" => [ + "jumlah" => $keluarMember->count(), + "income" => $keluarMember->sum("bayar_keluar"), + ], + "manual" => [ + "jumlah" => $keluarManual->count(), + "income" => $keluarManual->sum("bayar_keluar"), + ], + "masalah" => [ + "jumlah" => $keluarMasalah->count(), + "income" => $keluarMasalah->sum("bayar_keluar"), + ], + ], + "totalCash" => $totalCash, + ]; + }) + ->values(); + + $cashless = $transactions + ->sortBy("id_op_keluar") + ->groupBy("id_op_keluar") + ->map(function ($items, $id_op_keluar) { + // ====================== + // PISAH MASUK & KELUAR + // ====================== + // $masuk = $items->where('status', 1); + // $keluar = $items->where('status', 0); + // $nonTunai = $keluar->where('cara_bayar', 3); + $keluar = $items->filter(fn($r) => (int) $r->status === 0); + // $tunai = $keluar->where('cara_bayar', '!=', 3); + $nonTunai = $keluar->filter(fn($row) => (string) data_get($row, "cara_bayar") === "3"); + + // ====================== + // MASUK + // ====================== + // $masukCasual = $masuk->where('status_transaksi', '0'); + // $masukMember = $masuk->where('status_transaksi', '3'); + + // ====================== + // KELUAR + // ====================== + // $keluarCasual = $nonTunai->where('status_transaksi', '0'); + // $keluarMember = $nonTunai->where('status_transaksi', '3'); + // $keluarLost = $nonTunai->where('status_transaksi', '32'); + $keluarCasual = $nonTunai->filter( + fn($r) => (string) data_get($r, "status_transaksi") === "0" && data_get($r, "id_op_masuk") !== null, + ); + $keluarMember = $nonTunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "3"); + $keluarLost = $nonTunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "32"); + $keluarManual = $nonTunai->filter(fn($r) => data_get($r, "id_op_masuk") === null); + + $totalCashless = + $keluarCasual->sum("bayar_keluar") + + $keluarLost->sum("bayar_keluar") + + $keluarMember->sum("bayar_keluar") + + $keluarManual->sum("bayar_keluar"); + + // ====================== + // PEMBAYARAN (KELUAR) + // ====================== + + return [ + "id_petugas" => $id_op_keluar, + "petugas" => $items->first()->petugas, + "total" => $items->count(), + "nonTunaiOut" => $nonTunai->count(), + + // ========= MASUK ========= + // 'masuk' => [ + // 'casual' => [ + // 'jumlah' => $masukCasual->count(), + // 'income' => $masukCasual->sum('bayar_masuk'), + // ], + // 'member' => [ + // 'jumlah' => $masukMember->count(), + // 'income' => $masukMember->sum('bayar_masuk'), + // ], + // ], + + // ========= KELUAR ========= + "keluar" => [ + "casual" => [ + "jumlah" => $keluarCasual->count(), + "income" => $keluarCasual->sum("bayar_keluar"), + ], + "lost" => [ + "jumlah" => $keluarLost->count(), + "income" => $keluarLost->sum("bayar_keluar"), + ], + "member" => [ + "jumlah" => $keluarMember->count(), + "income" => $keluarMember->sum("bayar_keluar"), + ], + "manual" => [ + "jumlah" => $keluarManual->count(), + "income" => $keluarManual->sum("bayar_keluar"), + ], + ], + "totalCashless" => $totalCashless, + ]; + }) + ->values(); + + // $transactions = DB::table("transaksi_parkir as tp") + // ->leftJoin("pegawai as p", "p.nomer", "=", "tp.id_op_keluar") + // ->leftJoin("pegawai as pm", "pm.nomer", "=", "tp.id_op_masuk") + // ->leftJoin("pegawai as pk", "pk.nomer", "=", "tp.id_op_keluar") + // ->whereDate("waktu_masuk", "<", $dateNow) + // ->select( + // "tp.id_kendaraan", + // "p.nama as jenis_mobil", + // "tp.id_op_keluar", + // "p.nama as petugas", + // DB::raw("SUM(CASE WHEN tp.status = 1 THEN 1 ELSE 0 END) as overnight"), + // DB::raw("SUM(CASE WHEN tp.status = 3 THEN 1 ELSE 0 END) as onexpired"), + // ) + // ->groupBy("tp.id_op_keluar", "petugas") + // ->orderBy("tp.id_op_keluar", "asc") + // ->groupBy("p.nomer", "p.nama") + // ->orderBy("p.nomer") + // dd($transactions->toSql()); + // ->get(); + + // $onCheck = $transactions + // ->sortBy('id_kendaraan') + // ->groupBy('id_kendaraan') + // ->map(function ($items) { + // $overNight = $items->filter(fn ($r) => (int) $r->status === 1); + // $onExpired = $items->filter(fn ($r) => (int) $r->status === 3); + + // return [ + // "id_petugas" => $items->id_op_keluar, + // "petugas" => $items->petugas, + // "overNight" => (int) $items->overnight, + // "onExpired" => (int) $items->onexpired, + // ]; + // }) + // ->values(); + + Log::info("Rekap kendaraan selesai", [ + "total_kendaraan" => $tunai->count(), + ]); + + Log::info("== allReportData END ==", [ + "total_time_ms" => round((microtime(true) - $start) * 1000, 2), + ]); + + return [ + "date" => $startDate, + "tunai" => $tunai, + "nontunai" => $cashless, + ]; + } + // ========== End Laporan per petugas ===============/// + + // ==========###################### Begin Laporan per petugas #######################===============// + public function paymentType(Request $request) + { + Log::info("== Officer Report START =="); + Log::info($request->harian); + Log::info($request->tanggal); + $selectDate = $request->tanggal; + $start = microtime(true); + $harian = $request->harian ?? 1; + $dateNow = "2026-01-25"; + $startDate = $selectDate ? $selectDate : $dateNow; + $endDate = $selectDate ? $selectDate : $dateNow; + + Log::info("Tanggal laporan", [ + "start" => $startDate, + "end" => $endDate, + ]); + // ============= QUERY UTAMA (LEFT JOIN) ========================= + Log::info("Query transaksi dimulai"); + + if ($harian == 1) { + $dateColumn = ["tp.waktu_keluar"]; + } else { + $dateColumn = ["tp.pklogin"]; + } + + $transactions = DB::table("transaksi_parkir as tp") + // ->leftJoin("pegawai as p", "p.nomer", "=", "tp.id_op_keluar") + // ->leftJoin("pegawai as pm", "pm.nomer", "=", "tp.id_op_masuk") + // ->leftJoin("pegawai as pk", "pk.nomer", "=", "tp.id_op_keluar") + ->where(function ($q) use ($dateColumn, $startDate, $endDate, $selectDate) { + $q->whereBetween($dateColumn[0], [$startDate . " 00:00:00", $endDate . " 23:59:59"])->orWhereBetween( + $dateColumn[0], + [$startDate . " 00:00:00", $endDate . " 23:59:59"], + ); + // $q->whereRaw('DATE(tp.waktu_masuk) = ?', [$selectDate]) + // ->orWhereRaw('DATE(tp.waktu_keluar) = ?', [$selectDate]); + }) + // ->whereRaw("DATE($dateColumn) = ?", [$dateNow]) + // ->whereBetween($dateColumn, [$startDate, $endDate]) + ->select( + "rep_bank as bankType", + // "p.nomer as id_petugas", + // "p.nama as petugas", + // "tp.id_kendaraan", + + // "pm.nama as kasir_masuk", + // "pk.nama as kasir_keluar", + "tp.id_op_masuk", // โœ… ADA + "tp.id_op_keluar", + + "tp.waktu_masuk", + "tp.waktu_keluar", + "tp.status", + "tp.bayar_masuk", + "tp.bayar_keluar", + "tp.status_transaksi", + "tp.cara_bayar", + ) + ->get(); + Log::info("Query transaksi selesai", [ + "rows" => $transactions->count(), + "query_time_ms" => round((microtime(true) - $start) * 1000, 2), + ]); + + Log::info("Rekap payment dimulai"); + + $tunai = $transactions + ->sortBy("bankType") + ->groupBy("bankType") + ->map(function ($items, $bankType) { + $keluar = $items->filter(fn($r) => (int) $r->status === 0); + $tunai = $keluar->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true)); + $keluarCasual = $tunai->filter( + fn($r) => (string) data_get($r, "status_transaksi") === "0" && data_get($r, "id_op_masuk") !== null, + ); + $keluarMember = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "3"); + $keluarLost = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "32"); + $keluarManual = $tunai->filter(fn($r) => data_get($r, "id_op_masuk") === null); + $keluarMasalah = $tunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "-1"); + + $totalCash = + $keluarCasual->sum("bayar_keluar") + + $keluarLost->sum("bayar_keluar") + + $keluarMember->sum("bayar_keluar") + + $keluarManual->sum("bayar_keluar"); + + Log::info("Transaksi tunai : "); + + return [ + "typePayment" => $bankType, + "petugas" => $items->first()->bankType, + "total" => $items->count(), + "tunaiOut" => $tunai->count(), + "keluar" => [ + "casual" => [ + "jumlah" => $keluarCasual->count(), + "income" => $keluarCasual->sum("bayar_keluar"), + ], + "lost" => [ + "jumlah" => $keluarLost->count(), + "income" => $keluarLost->sum("bayar_keluar"), + ], + "member" => [ + "jumlah" => $keluarMember->count(), + "income" => $keluarMember->sum("bayar_keluar"), + ], + "manual" => [ + "jumlah" => $keluarManual->count(), + "income" => $keluarManual->sum("bayar_keluar"), + ], + "masalah" => [ + "jumlah" => $keluarMasalah->count(), + "income" => $keluarMasalah->sum("bayar_keluar"), + ], + ], + "totalCash" => $totalCash, + ]; + }) + ->values(); + + $cashless = $transactions + ->sortBy("bankType") + ->groupBy("bankType") + ->map(function ($items, $bankType) { + $keluar = $items->filter(fn($r) => (int) $r->status === 0); + $nonTunai = $keluar->filter(fn($row) => (string) data_get($row, "cara_bayar") === "3"); + + $keluarCasual = $nonTunai->filter( + fn($r) => (string) data_get($r, "status_transaksi") === "0" && data_get($r, "id_op_masuk") !== null, + ); + $keluarMember = $nonTunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "3"); + $keluarLost = $nonTunai->filter(fn($r) => (string) data_get($r, "status_transaksi") === "32"); + $keluarManual = $nonTunai->filter(fn($r) => data_get($r, "id_op_masuk") === null); + + $totalCashless = + $keluarCasual->sum("bayar_keluar") + + $keluarLost->sum("bayar_keluar") + + $keluarMember->sum("bayar_keluar") + + $keluarManual->sum("bayar_keluar"); + + // ====================== + // PEMBAYARAN (KELUAR) + // ====================== + + return [ + "typePayment" => $bankType, + "petugas" => $items->first()->bankType, + "total" => $items->count(), + "nonTunaiOut" => $nonTunai->count(), + "keluar" => [ + "casual" => [ + "jumlah" => $keluarCasual->count(), + "income" => $keluarCasual->sum("bayar_keluar"), + ], + "lost" => [ + "jumlah" => $keluarLost->count(), + "income" => $keluarLost->sum("bayar_keluar"), + ], + "member" => [ + "jumlah" => $keluarMember->count(), + "income" => $keluarMember->sum("bayar_keluar"), + ], + "manual" => [ + "jumlah" => $keluarManual->count(), + "income" => $keluarManual->sum("bayar_keluar"), + ], + ], + "totalCashless" => $totalCashless, + ]; + }) + ->values(); + + Log::info("Rekap kendaraan selesai", [ + "total_kendaraan" => $tunai->count(), + ]); + + Log::info("== allReportData END ==", [ + "total_time_ms" => round((microtime(true) - $start) * 1000, 2), + ]); + + return [ + "date" => $startDate, + "tunai" => $tunai, + "nontunai" => $cashless, + ]; + } + // ========== End Laporan payment Type ===============/// } diff --git a/app/Http/Controllers/Parking/Setup/UserLevel/LevelMenuController.php b/app/Http/Controllers/Parking/Setup/UserLevel/LevelMenuController.php new file mode 100644 index 0000000..6ebd7c6 --- /dev/null +++ b/app/Http/Controllers/Parking/Setup/UserLevel/LevelMenuController.php @@ -0,0 +1,85 @@ + "Tidak ada perubahan data", ]); } - Log::info( - "Data yang di simpan" . json_encode($dataQuery->getDirty()), - ); + Log::info("Data yang di simpan" . json_encode($dataQuery->getDirty())); $dataQuery->save(); return response()->json([ @@ -102,9 +100,7 @@ public function update(Request $request, $id) "message" => "Data berhasil di ubah", ]); } catch (\Throwable $th) { - Log::info( - "Data yang di simpan" . json_encode($dataQuery->getDirty()), - ); + Log::info("Data yang di simpan" . json_encode($dataQuery->getDirty())); // Log::info($request->all()); diff --git a/app/Http/Controllers/ParkingSetupUserLevelLevelMenuController.php b/app/Http/Controllers/ParkingSetupUserLevelLevelMenuController.php new file mode 100644 index 0000000..f88daca --- /dev/null +++ b/app/Http/Controllers/ParkingSetupUserLevelLevelMenuController.php @@ -0,0 +1,84 @@ + String(nt.id_kendaraan) === String(cash.id_kendaraan)); + // // fallback aman + // cashless = cashless || { + // nontunai: 0, + // nonTunaiOut: 0, + // keluar: { + // casual: { jumlah: 0, income: 0 }, + // lost: { jumlah: 0, income: 0 }, + // member: { jumlah: 0, income: 0 }, + // }, + // totalCashless: 0, + // }; + // let casualIn = cash.total; + // let tunaiOut = cash.tunaiOut; + // // ===== DATA TUNAI ===== + // let tCasual = cash.keluar.casual; + // let tLost = cash.keluar.lost; + // let tMember = cash.keluar.member; + // let tManual = cash.keluar.manual; + // // ===== DATA NON TUNAI ===== + // let nonTunaiOut = cashless.nonTunaiOut; + // let nCasual = cashless.keluar.casual; + // let nLost = cashless.keluar.lost; + // let nMember = cashless.keluar.member; + // let nManual = cashless.keluar.manual; + // let totalTunai = cash.totalCash || 0; + // let totalNonTunai = cashless.totalCashless || 0; + // jmlCashCasual += cash.keluar.casual.jumlah; + // incomeCashCasual += cash.keluar.casual.income; + // jmlCashlessCasual += cashless.keluar.casual.jumlah; + // incomeCashlessCasual += cashless.keluar.casual.income; + // grandTotal += totalTunai + totalNonTunai; + // // let casualCash = cash.keluar.casual; + // // let lostCash = cash.keluar.lost; + // // let memberCash = cash.keluar.member; + // // let casualIn = cash.total; + // // let casualNon = cashless ? cashless.keluar.casual : { jumlah: 0, income: 0 }; + // // let lostNon = cashless ? cashless.keluar.lost : { jumlah: 0, income: 0 }; + // // let memberNon = cashless ? cashless.keluar.member : { jumlah: 0, income: 0 }; + // // let totalIncome = + // // (cash.totalCash || 0); + // // html += ` + // // + // // ${cash.jenis_mobil} + // // + // // ${casualIn} + // // ${cash.tunaiOut} + // // + // // ${casualCash.jumlah} + // // ${rupiah(casualCash.income)} + // // + // // ${lostCash.jumlah} + // // ${rupiah(lostCash.income)} + // // + // // ${memberCash.jumlah} + // // ${rupiah(memberCash.income)} + // // + // // 0 + // // 0 + // // + // // 0 + // // 0 + // // + // // 0 + // // 0 + // // + // // ${rupiah(totalIncome)} + // // + // // `; + // html += ` + // + // ${cash.jenis_mobil} + // Tunai + // ${casualIn} + // ${tunaiOut} + // ${tCasual.jumlah} + // ${rupiah(tCasual.income)} + // ${tLost.jumlah} + // ${rupiah(tLost.income)} + // ${tMember.jumlah} + // ${rupiah(tMember.income)} + // ${tManual.jumlah} + // ${rupiah(tManual.income)} + // 0 + // 0 + // 0 + // 0 + // ${rupiah(totalTunai)} + // + // + // Non Tunai + // ${casualIn} + // ${nonTunaiOut} + // ${nCasual.jumlah} + // ${rupiah(nCasual.income)} + // ${nLost.jumlah} + // ${rupiah(nLost.income)} + // ${nMember.jumlah} + // ${rupiah(nMember.income)} + // ${nManual.jumlah} + // ${rupiah(nManual.income)} + // 0 + // 0 + // 0 + // 0 + // ${rupiah(totalNonTunai)} + // + // `; + // }); + // // ===== FOOTER TOTAL ===== + // html += ` + // + // TOTAL + // Tunai + // 0 + // 0 + // ${rupiah(jmlCashCasual)} + // ${rupiah(incomeCashCasual)} + // 0 + // + // + // NON TUNAI + // 0 + // 0 + // ${jmlCashlessCasual} + // ${rupiah(incomeCashlessCasual)} + // 0 + // + // + // GRAND TOTAL + // + // ${jmlCashCasual + jmlCashlessCasual} + // ${rupiah(incomeCashCasual + incomeCashlessCasual)} + // + // + // + // + // + // + // + // + // + // + // ${rupiah(grandTotal)} + // + // `; + // // console.log('TUNAI:', cash.id_kendaraan, cash); + // // console.log('CASHLESS FOUND:', cashless); + // $("#table-data").html(html); + // response.overNight.forEach(function (on) { + // if (!on.jenis_mobil) return; + // let overnight = on.overNight; + // let onExpired = on.onExpired; + // onData += ` + // + // ${on.jenis_mobil} + // ${overnight} + // ${onExpired} + // 0 + // + // `; + // }); + // $("#table-overnight").html(onData); + // console.log(response); + }, + error: function (xhr) { + console.log("Error:", xhr); + alert("Terjadi kesalahan saat memuat data"); + }, + }); +} + +function rupiah(angka) { + return new Intl.NumberFormat("id-ID").format(angka || 0); +} + +function getToday() { + const d = new Date(); + const tgl = String(d.getDate()).padStart(2, "0"); + const bulan = String(d.getMonth() + 1).padStart(2, "0"); + const tahun = d.getFullYear(); + return `${tgl}-${bulan}-${tahun}`; +} + +function tableVehicle(response) { + // Update tabel dengan data yang diterima + + let html = ""; + let onData = ""; + let jmlCashCasual = 0; + let incomeCashCasual = 0; + + let jmlCashlessCasual = 0; + let incomeCashlessCasual = 0; + + let grandTotal = 0; + + response.tunai.forEach(function (cash) { + // cari pasangan non tunai + let cashless = response.nontunai.find((nt) => String(nt.id_kendaraan) === String(cash.id_kendaraan)); + + // fallback aman + cashless = cashless || { + nontunai: 0, + nonTunaiOut: 0, + keluar: { + casual: { jumlah: 0, income: 0 }, + lost: { jumlah: 0, income: 0 }, + member: { jumlah: 0, income: 0 }, + }, + totalCashless: 0, + }; + + let casualIn = cash.total; + let tunaiOut = cash.tunaiOut; + // ===== DATA TUNAI ===== + let tCasual = cash.keluar.casual; + let tLost = cash.keluar.lost; + let tMember = cash.keluar.member; + let tManual = cash.keluar.manual; + + // ===== DATA NON TUNAI ===== + let nonTunaiOut = cashless.nonTunaiOut; + + let nCasual = cashless.keluar.casual; + let nLost = cashless.keluar.lost; + let nMember = cashless.keluar.member; + let nManual = cashless.keluar.manual; + + let totalTunai = cash.totalCash || 0; + let totalNonTunai = cashless.totalCashless || 0; + + jmlCashCasual += cash.keluar.casual.jumlah; + incomeCashCasual += cash.keluar.casual.income; + + jmlCashlessCasual += cashless.keluar.casual.jumlah; + incomeCashlessCasual += cashless.keluar.casual.income; + + grandTotal += totalTunai + totalNonTunai; + // let casualCash = cash.keluar.casual; + // let lostCash = cash.keluar.lost; + // let memberCash = cash.keluar.member; + // let casualIn = cash.total; + + // let casualNon = cashless ? cashless.keluar.casual : { jumlah: 0, income: 0 }; + // let lostNon = cashless ? cashless.keluar.lost : { jumlah: 0, income: 0 }; + // let memberNon = cashless ? cashless.keluar.member : { jumlah: 0, income: 0 }; + + // let totalIncome = + // (cash.totalCash || 0); + + // html += ` + // + // ${cash.jenis_mobil} + + // + // ${casualIn} + // ${cash.tunaiOut} + + // + // ${casualCash.jumlah} + // ${rupiah(casualCash.income)} + + // + // ${lostCash.jumlah} + // ${rupiah(lostCash.income)} + + // + // ${memberCash.jumlah} + // ${rupiah(memberCash.income)} + + // + // 0 + // 0 + + // + // 0 + // 0 + + // + // 0 + // 0 + + // + // ${rupiah(totalIncome)} + // + // `; + html += ` + + ${cash.jenis_mobil} + Tunai + + ${casualIn} + ${tunaiOut} + + ${tCasual.jumlah} + ${rupiah(tCasual.income)} + + ${tLost.jumlah} + ${rupiah(tLost.income)} + + ${tMember.jumlah} + ${rupiah(tMember.income)} + + ${tManual.jumlah} + ${rupiah(tManual.income)} + + 0 + 0 + + 0 + 0 + + ${rupiah(totalTunai)} + + + + Non Tunai + + ${casualIn} + ${nonTunaiOut} + + ${nCasual.jumlah} + ${rupiah(nCasual.income)} + + ${nLost.jumlah} + ${rupiah(nLost.income)} + + ${nMember.jumlah} + ${rupiah(nMember.income)} + + ${nManual.jumlah} + ${rupiah(nManual.income)} + + 0 + 0 + + 0 + 0 + + ${rupiah(totalNonTunai)} + + `; + }); + + // ===== FOOTER TOTAL ===== + html += ` + + TOTAL + Tunai + 0 + 0 + ${rupiah(jmlCashCasual)} + ${rupiah(incomeCashCasual)} + + ${rupiah(incomeCashCasual)} + + + NON TUNAI + 0 + 0 + ${jmlCashlessCasual} + ${rupiah(incomeCashlessCasual)} + + ${rupiah(incomeCashlessCasual)} + + + GRAND TOTAL + + ${jmlCashCasual + jmlCashlessCasual} + ${rupiah(incomeCashCasual + incomeCashlessCasual)} + + + + + + + + + + + ${rupiah(grandTotal)} + + `; + // console.log('TUNAI:', cash.id_kendaraan, cash); + // console.log('CASHLESS FOUND:', cashless); + + $("#table-data").html(html); + + response.overNight.forEach(function (on) { + if (!on.jenis_mobil) return; + + let overnight = on.overNight; + let onExpired = on.onExpired; + + onData += ` + + ${on.jenis_mobil} + ${overnight} + ${onExpired} + 0 + + `; + }); + + $("#table-overnight").html(onData); + console.log(response); +} + +function tableOfficer(response) { + // Update tabel dengan data yang diterima + console.log(response); + + let html = ""; + let onData = ""; + let jmlCashCasual = 0; + let incomeCashCasual = 0; + + let jmlCashlessCasual = 0; + let incomeCashlessCasual = 0; + + let grandTotal = 0; + + response.tunai.forEach(function (cash) { + // cari pasangan non tunai + let cashless = response.nontunai.find((nt) => String(nt.id_petugas) === String(cash.id_petugas)); + + // fallback aman + cashless = cashless || { + nontunai: 0, + nonTunaiOut: 0, + keluar: { + casual: { jumlah: 0, income: 0 }, + lost: { jumlah: 0, income: 0 }, + member: { jumlah: 0, income: 0 }, + }, + totalCashless: 0, + }; + + let petugas = cash.petugas === null ? "NO-OP" : cash.petugas; + let casualIn = cash.total; + let tunaiOut = cash.tunaiOut; + // ===== DATA TUNAI ===== + let tCasual = cash.keluar.casual; + let tLost = cash.keluar.lost; + let tMember = cash.keluar.member; + let tManual = cash.keluar.manual; + + // ===== DATA NON TUNAI ===== + let nonTunaiOut = cashless.nonTunaiOut; + + let nCasual = cashless.keluar.casual; + let nLost = cashless.keluar.lost; + let nMember = cashless.keluar.member; + let nManual = cashless.keluar.manual ?? 0; + + let totalTunai = cash.totalCash || 0; + let totalNonTunai = cashless.totalCashless || 0; + + jmlCashCasual += cash.keluar.casual.jumlah; + incomeCashCasual += cash.keluar.casual.income; + + jmlCashlessCasual += cashless.keluar.casual.jumlah; + incomeCashlessCasual += cashless.keluar.casual.income; + + grandTotal += totalTunai + totalNonTunai; + // let casualCash = cash.keluar.casual; + // let lostCash = cash.keluar.lost; + // let memberCash = cash.keluar.member; + // let casualIn = cash.total; + + // let casualNon = cashless ? cashless.keluar.casual : { jumlah: 0, income: 0 }; + // let lostNon = cashless ? cashless.keluar.lost : { jumlah: 0, income: 0 }; + // let memberNon = cashless ? cashless.keluar.member : { jumlah: 0, income: 0 }; + + // let totalIncome = + // (cash.totalCash || 0); + + // html += ` + // + // ${cash.jenis_mobil} + + // + // ${casualIn} + // ${cash.tunaiOut} + + // + // ${casualCash.jumlah} + // ${rupiah(casualCash.income)} + + // + // ${lostCash.jumlah} + // ${rupiah(lostCash.income)} + + // + // ${memberCash.jumlah} + // ${rupiah(memberCash.income)} + + // + // 0 + // 0 + + // + // 0 + // 0 + + // + // 0 + // 0 + + // + // ${rupiah(totalIncome)} + // + // `; + html += ` + + ${petugas} + Tunai + + ${casualIn} + ${tunaiOut} + + ${tCasual.jumlah} + ${rupiah(tCasual.income)} + + ${tLost.jumlah} + ${rupiah(tLost.income)} + + ${tMember.jumlah} + ${rupiah(tMember.income)} + + ${tManual.jumlah} + ${rupiah(tManual.income)} + + 0 + 0 + + 0 + + + ${rupiah(totalTunai)} + + + + Non Tunai + + ${casualIn} + ${nonTunaiOut} + + ${nCasual.jumlah} + ${rupiah(nCasual.income)} + + ${nLost.jumlah} + ${rupiah(nLost.income)} + + ${nMember.jumlah} + ${rupiah(nMember.income)} + + ${nManual.jumlah} + ${rupiah(nManual.income)} + + 0 + 0 + + 0 + 0 + + ${rupiah(totalNonTunai)} + + `; + }); + + // ===== FOOTER TOTAL ===== + html += ` + + TOTAL + Tunai + 0 + 0 + ${rupiah(jmlCashCasual)} + ${rupiah(incomeCashCasual)} + ${rupiah(incomeCashCasual)} + + + NON TUNAI + 0 + 0 + ${jmlCashlessCasual} + ${rupiah(incomeCashlessCasual)} + ${rupiah(incomeCashlessCasual)} + + + GRAND TOTAL + + ${jmlCashCasual + jmlCashlessCasual} + ${rupiah(incomeCashCasual + incomeCashlessCasual)} + + + + + + + + + + + ${rupiah(grandTotal)} + + `; + // console.log('TUNAI:', cash.id_kendaraan, cash); + // console.log('CASHLESS FOUND:', cashless); + + $("#officer-data").html(html); + + // response.overNight.forEach(function (on) { + // if (!on.jenis_mobil) return; + + // let overnight = on.overNight; + // let onExpired = on.onExpired; + + // onData += ` + // + // ${on.jenis_mobil} + // ${overnight} + // ${onExpired} + // 0 + // + // `; + // }); + + // $("#table-overnight").html(onData); + // console.log(response); +} + +function tablePayment(response) { + // Update tabel dengan data yang diterima + console.log(response); + + let html = ""; + let onData = ""; + let jmlCashCasual = 0; + let incomeCashCasual = 0; + + let jmlCashlessCasual = 0; + let incomeCashlessCasual = 0; + + let grandTotal = 0; + + response.tunai.forEach(function (cash) { + // cari pasangan non tunai + let cashless = response.nontunai.find((nt) => String(nt.typePayment) === String(cash.typePayment)); + + // fallback aman + cashless = cashless || { + nontunai: 0, + nonTunaiOut: 0, + keluar: { + casual: { jumlah: 0, income: 0 }, + lost: { jumlah: 0, income: 0 }, + member: { jumlah: 0, income: 0 }, + }, + totalCashless: 0, + }; + + let payment = paymentType(cash.typePayment); + // let payment = cash.typePayment; + let casualIn = cash.total; + let tunaiOut = cash.tunaiOut; + // ===== DATA TUNAI ===== + let tCasual = cash.keluar.casual; + let tLost = cash.keluar.lost; + let tMember = cash.keluar.member; + let tManual = cash.keluar.manual; + + // ===== DATA NON TUNAI ===== + let nonTunaiOut = cashless.nonTunaiOut; + + let nCasual = cashless.keluar.casual; + let nLost = cashless.keluar.lost; + let nMember = cashless.keluar.member; + let nManual = cashless.keluar.manual ?? 0; + + let totalTunai = cash.totalCash || 0; + let totalNonTunai = cashless.totalCashless || 0; + + jmlCashCasual += cash.keluar.casual.jumlah; + incomeCashCasual += cash.keluar.casual.income; + + jmlCashlessCasual += cashless.keluar.casual.jumlah; + incomeCashlessCasual += cashless.keluar.casual.income; + + grandTotal += totalTunai + totalNonTunai; + html += ` + + ${payment} + Tunai + + ${casualIn} + ${tunaiOut} + + ${tCasual.jumlah} + ${rupiah(tCasual.income)} + + ${tLost.jumlah} + ${rupiah(tLost.income)} + + ${tMember.jumlah} + ${rupiah(tMember.income)} + + ${tManual.jumlah} + ${rupiah(tManual.income)} + + 0 + 0 + + 0 + + + ${rupiah(totalTunai)} + + + + Non Tunai + + ${casualIn} + ${nonTunaiOut} + + ${nCasual.jumlah} + ${rupiah(nCasual.income)} + + ${nLost.jumlah} + ${rupiah(nLost.income)} + + ${nMember.jumlah} + ${rupiah(nMember.income)} + + ${nManual.jumlah} + ${rupiah(nManual.income)} + + 0 + 0 + + 0 + 0 + + ${rupiah(totalNonTunai)} + + `; + }); + + // ===== FOOTER TOTAL ===== + html += ` + + TOTAL + Tunai + 0 + 0 + ${rupiah(jmlCashCasual)} + ${rupiah(incomeCashCasual)} + ${rupiah(incomeCashCasual)} + + + NON TUNAI + 0 + 0 + ${jmlCashlessCasual} + ${rupiah(incomeCashlessCasual)} + ${rupiah(incomeCashlessCasual)} + + + GRAND TOTAL + + ${jmlCashCasual + jmlCashlessCasual} + ${rupiah(incomeCashCasual + incomeCashlessCasual)} + + + + + + + + + + + ${rupiah(grandTotal)} + + `; + // console.log('TUNAI:', cash.id_kendaraan, cash); + // console.log('CASHLESS FOUND:', cashless); + + $("#payment-data").html(html); +} + +function paymentType(value) { + switch (value) { + case 2: + value = "Mandiri"; + break; + case 3: + value = "BRIZZI"; + break; + case 4: + value = "TapCash"; + break; + case 5: + value = "Flazz"; + break; + case 9: + value = "QRIS"; + break; + default: + value = "Tunai"; + } + + return value; +} + +function printPDF(vehicle) { + const { jsPDF } = window.jspdf; + const doc = new jsPDF({ + orientation: "portait", // portrait kesempitan buat 16 kolom + unit: "mm", + format: "a4", + }); + + const pageWidth = doc.internal.pageSize.getWidth(); + + // ===== HEADER ===== + doc.setFont("helvetica", "bold"); + doc.setFontSize(12); + doc.text("MENTENG SQUARE - RAYA PARKING - RAYA Parking", 14, 12); + + doc.setFontSize(11); + doc.text("Rekap Transaksi Kendaraan", pageWidth / 2, 18, { align: "center" }); + + doc.setFont("helvetica", "normal"); + doc.setFontSize(9); + doc.text("Tanggal : " + (vehicle.date ?? "-"), pageWidth / 2, 23, { align: "center" }); + doc.text("By : Harian", pageWidth - 14, 12, { align: "right" }); + + // ===== SUSUN BODY TABEL ===== + const body = []; + let totalTunaiJml = 0, + totalTunaiNilai = 0; + let totalNonTunaiJml = 0, + totalNonTunaiNilai = 0; + let grandTotal = 0; + + vehicle.tunai.forEach(function (cash) { + const cashless = vehicle.nontunai.find((nt) => String(nt.id_kendaraan) === String(cash.id_kendaraan)) || { + nonTunaiOut: 0, + keluar: { + casual: { jumlah: 0, income: 0 }, + lost: { jumlah: 0, income: 0 }, + member: { jumlah: 0, income: 0 }, + manual: { jumlah: 0, income: 0 }, + }, + totalCashless: 0, + }; + // debugger; + + const tCasual = cash.keluar.casual; + const tLost = cash.keluar.lost; + const tMember = cash.keluar.member; + const tManual = cash.keluar.manual; + const tMasalah = cash.keluar.masalah ?? { jumlah: 0, income: 0 }; + const totalTunai = cash.totalCash || 0; + + const nCasual = cashless.keluar.casual; + const nLost = cashless.keluar.lost; + const nMember = cashless.keluar.member; + const nManual = cashless.keluar.manual; + const nMasalah = cashless.keluar.masalah ?? { jumlah: 0, income: 0 }; + const totalNonTunai = cashless.totalCashless || 0; + + // baris TUNAI + body.push([ + { content: cash.jenis_mobil, rowSpan: 2, styles: { valign: "middle" } }, + { content: "Tunai", styles: { fillColor: [40, 167, 69], textColor: 255, fontStyle: "bold" } }, + cash.total, + cash.tunaiOut, + tCasual.jumlah, + rupiah(tCasual.income), + tLost.jumlah, + rupiah(tLost.income), + tMember.jumlah, + rupiah(tMember.income), + tManual.jumlah, + rupiah(tManual.income), + 0, + 0, + tMasalah.jumlah, + rupiah(tMasalah.income), + { content: rupiah(cash.totalCash), styles: { valign: "middle", fontStyle: "bold" } }, + ]); + + // baris NON TUNAI + body.push([ + { content: "Non Tunai", styles: { fillColor: [255, 193, 7], textColor: 0, fontStyle: "bold" } }, + + cash.total, + cashless.nonTunaiOut, + + nCasual.jumlah, + rupiah(nCasual.income), + + nLost.jumlah, + // rupiah(nLost.income), + cash.totalCashless, + + nMember.jumlah, + rupiah(nMember.income), + + nManual.jumlah, + rupiah(nManual.income), + + 0, + 0, + + nMasalah.jumlah, + rupiah(nMasalah.income), + + { content: rupiah(cashless.totalCashless), styles: { valign: "middle", fontStyle: "bold" } }, + ]); + + totalTunaiJml += tCasual.jumlah + tLost.jumlah + tMember.jumlah + tManual.jumlah + tMasalah.jumlah; + totalTunaiNilai += cash.totalCash || 0; + totalNonTunaiJml += nCasual.jumlah + nLost.jumlah + nMember.jumlah + nManual.jumlah + nMasalah.jumlah; + totalNonTunaiNilai += cashless.totalCashless || 0; + grandTotal += (cash.totalCash || 0) + (cashless.totalCashless || 0); + }); + + // baris TOTAL & GRAND TOTAL + body.push([ + { content: "TOTAL", rowSpan: 2, styles: { fontStyle: "bold" } }, + { content: "Tunai", styles: { fillColor: [40, 167, 69], textColor: 255, fontStyle: "bold" } }, + "", + "", + { content: totalTunaiJml, styles: { fontStyle: "bold" } }, + rupiah(totalTunaiNilai), + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + rupiah(totalTunaiNilai), + ]); + body.push([ + { content: "NON TUNAI", styles: { fillColor: [255, 193, 7], fontStyle: "bold" } }, + "", + "", + { content: totalNonTunaiJml, styles: { fontStyle: "bold" } }, + rupiah(totalNonTunaiNilai), + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + rupiah(totalNonTunaiNilai), + ]); + body.push([ + { content: "GRAND TOTAL", colSpan: 4, styles: { fontStyle: "bold", halign: "center" } }, + { content: totalTunaiJml + totalNonTunaiJml, styles: { fontStyle: "bold" } }, + { content: rupiah(totalTunaiNilai + totalNonTunaiNilai), styles: { fontStyle: "bold" } }, + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + { content: rupiah(grandTotal), styles: { fontStyle: "bold" } }, + ]); + + // ===== HEADER 2 BARIS (grouping) ===== + const head = [ + [ + { content: "Jenis Kend", rowSpan: 2, colSpan: 2 }, + { content: "Jenis Transaksi", colSpan: 2 }, + { content: "Casual", colSpan: 2 }, + { content: "Tiket Hilang", colSpan: 2 }, + { content: "Member", colSpan: 2 }, + { content: "Manual Input", colSpan: 2 }, + { content: "Manual Mix", colSpan: 2 }, + { content: "Tiket Masalah", colSpan: 2 }, + { content: "Pendapatan", rowSpan: 2 }, + ], + [ + "Masuk", + "Keluar", + "JML", + "Nilai", + "JML", + "Nilai", + "JML", + "Nilai", + "JML", + "Nilai", + "JML", + "Nilai", + "JML", + "Nilai", + ], + ]; + + doc.autoTable({ + head: head, + body: body, + startY: 28, + theme: "grid", + styles: { fontSize: 6, halign: "center", valign: "middle", lineColor: [200, 200, 200] }, + headStyles: { fillColor: [230, 230, 230], textColor: 0, fontStyle: "bold" }, + columnStyles: { 0: { halign: "left" } }, + }); + + // ===== TABEL OVER NIGHT (di bawah tabel utama) ===== + const onBody = vehicle.overNight.map((on) => [ + on.jenis_mobil ?? "-", + on.overNight, + on.onExpired, + (on.overNight || 0) + (on.onExpired || 0), + ]); + + doc.setFont("helvetica", "bold"); + doc.setFontSize(8); + doc.text("Kendaraan yang masih menginap (Over Night)", 14, doc.lastAutoTable.finalY + 10); + + doc.autoTable({ + head: [["Jenis Kend", "Menginap", "ON (Expired)", "Total"]], + body: onBody, + startY: doc.lastAutoTable.finalY + 13, + theme: "grid", + styles: { fontSize: 7, cellPadding: 1 }, + headStyles: { fontSize: 8, fillColor: [230, 230, 230], textColor: 0 }, + tableWidth: 100, + }); + + doc.save(`Rekap Harian - ${vehicle.date}.pdf`); +} diff --git a/resources/views/report/all-report.blade.php b/resources/views/report/all-report.blade.php index 90dd794..a18784f 100644 --- a/resources/views/report/all-report.blade.php +++ b/resources/views/report/all-report.blade.php @@ -2,6 +2,7 @@ @section('styles') +