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; // ๐Ÿ”น 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'), ]; // ๐Ÿ”น Tambah shift kalau aktif if ($isShift) { $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', ]; if ($isShift) { $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') ->select($select) // ๐Ÿ”น Filter tanggal (dynamic field) ->where('tp.status', 0) ->whereBetween($dateBy, [ $awal . ' 00:00:00', $akhir . ' 23:59:59' ]) // // ๐Ÿ”น STATUS // ->when($request->status_transaksi, fn($q, $v) => // $q->where('tp.status_transaksi', $v) // ) // ๐Ÿ”น PINTU ->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) { return match ($request->status_transaksi) { '3' => $q->where('tp.status_transaksi', '3'), '0' => $q->where('tp.status_transaksi', '0'), '-1' => $q->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 }; }) ->when($paymentMethod, function ($q) use ($paymentMethod) { return $q->where('tp.rep_bank', $paymentMethod); // return match ($request->payment_method) { // 2 => $q->where('tp.rep_bank', 2), // 3 => $q->where('tp.rep_bank', 3), // 4 => $q->where('tp.rep_bank', 4), // 5 => $q->where('tp.rep_bank', 5), // 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) // ) // // ๐Ÿ”น KENDARAAN // ->when($request->id_kendaraan, fn($q, $v) => // $q->whereIn('tp.id_kendaraan', (array) $v) // ) ->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'); return response()->json([ 'byGateData' => $query->get() ]); } public function allReport () { return view ('report.all-report'); } public function allReportData(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'; $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('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->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', 'pm.nama as kasir_masuk', 'pk.nama as kasir_keluar', 'tp.id_op_masuk', '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) ]); // ========================= // REKAP PER KENDARAAN // ========================= Log::info('Rekap kendaraan dimulai'); $tunai = $transactions ->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); // $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'); return [ 'id_kendaraan' => $idKendaraan, 'jenis_mobil' => $items->first()->jenis_mobil, '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_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); // $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_kendaraan' => $idKendaraan, 'jenis_mobil' => $items->first()->jenis_mobil, '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('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', 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_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, ]; } )->values(); Log::info('Rekap kendaraan selesai', [ 'total_kendaraan' => $tunai->count() ]); Log::info('== allReportData END ==', [ 'total_time_ms' => round((microtime(true) - $start) * 1000, 2) ]); return response()->json([ // 'date' => $startDate->format('Y-m-d'),รท 'date' => $startDate, 'tunai' => $tunai, 'nontunai' => $cashless, 'overNight' => $onCheck // 'transactions' => $transactions->groupBy('id_kendaraan') ]); } }