456 lines
17 KiB
PHP
456 lines
17 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\TransaksiParkir;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class ReportTransaksiController extends Controller
|
|
{
|
|
public function byGate ()
|
|
{
|
|
return view ('report.by-gate');
|
|
}
|
|
|
|
public function gateData(Request $request)
|
|
{
|
|
Log::info($request->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)
|
|
)
|
|
|
|
// 🔹 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')
|
|
]);
|
|
}
|
|
|
|
}
|