Rapihin setup/member/lot-parking + fitur intercom, exclude WIP controller & file sampah dari git
Kumpulan perubahan yang udah numpuk di working tree: refactor Setup (Gate/Vehicle/Member), rapihin memberin & stiker, service parking baru (ParkingUtilsServices, NetworkService), model/migration lot-parking & DHCP reservation, dan fitur baru Intercom (controller/model/migration/ view). ReportTransaksiController versi lokal ini WIP (~90%, masih didebug) - versi yang bener ada di server, jadi dikeluarin dari git (ditambahin ke .gitignore) biar gak numpuk nindihin punya server pas git pull di sana. Sekalian keluarin dump mentah tabel softseting (1.8MB, nyasar ke-commit), file .bak, dan arsip ad-hoc (api.tgz, c.zip) yang emang bukan source code. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EAJc2mrpj2cSTe4oowLPzQ
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Parking\Audit;
|
||||
|
||||
use App\Models\TransaksiParkir;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
|
||||
class AuditReportController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view("Parking.Audit.index");
|
||||
}
|
||||
|
||||
public function data(Request $request)
|
||||
{
|
||||
$query = TransaksiParkir::query()
|
||||
->from("transaksi_parkir as tp")
|
||||
->leftJoin("pegawai as p", "p.nomer", "=", "tp.adm");
|
||||
|
||||
// Tanggal wajib
|
||||
$query->whereBetween("waktu_keluar", [$request->start_date . " 00:00:00", $request->end_date . " 23:59:59"]);
|
||||
|
||||
// Status
|
||||
if ($request->filled("status_transaksi")) {
|
||||
$query->where("status_transaksi", $request->status_transaksi);
|
||||
} else {
|
||||
// Default hanya -1 dan -2
|
||||
$query->whereIn("status_transaksi", [0, -1, -2]);
|
||||
}
|
||||
|
||||
// Alasan tidak boleh NULL
|
||||
if ($request->filter_alasan == "1") {
|
||||
$query->whereNotNull("alasan");
|
||||
}
|
||||
|
||||
$totalTransaksi = (clone $query)->count();
|
||||
|
||||
$totalBayar = (clone $query)->sum("bayar_keluar");
|
||||
|
||||
$data = $query
|
||||
->select([
|
||||
"tp.id",
|
||||
"no_pol",
|
||||
"waktu_masuk",
|
||||
"waktu_keluar",
|
||||
"status_transaksi",
|
||||
"bayar_keluar",
|
||||
"alasan",
|
||||
"cara_bayar",
|
||||
"p.nama as operator",
|
||||
])
|
||||
->orderByDesc("waktu_keluar")
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
"response" => true,
|
||||
"data" => $data,
|
||||
"summary" => [
|
||||
"total_transaksi" => $totalTransaksi,
|
||||
"total_bayar" => $totalBayar,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,14 @@
|
||||
namespace App\Http\Controllers\Parking;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\MemberCard;
|
||||
use App\Models\SoftSettings;
|
||||
use App\Models\StikerTrans;
|
||||
use App\Models\StikerTransDetail;
|
||||
use App\Models\MemberCard;
|
||||
use App\Services\MakeStikerServices;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@@ -35,12 +38,22 @@ public function index(Request $request)
|
||||
|
||||
public function getMember(Request $request)
|
||||
{
|
||||
// Log::info(json_encode("nopol : " . $request->nopol));
|
||||
Log::info(json_encode("nama : " . $request->input("search-by")));
|
||||
Log::info(json_encode("value : " . $request->input("search_value")));
|
||||
Log::info(json_encode("isActive : " . $request->input("isActive")));
|
||||
// Log::info(json_encode("veh : " . $request->vehicle));
|
||||
// Log::info(json_encode("dept : " . $request->depart));
|
||||
// Log::info(json_encode("mem : " . $request->member));
|
||||
// Log::info(json_encode("mem : " . $request->jenismember));
|
||||
// Log::info(json_encode("trans : " . $request->notrans));
|
||||
// Log::info(json_encode("isactive : " . gettype($request->isactive)));
|
||||
$searchBy = $request->input("search-by");
|
||||
$searchValue = trim($request->input("search_value", ""));
|
||||
|
||||
$memberType = $request->input("member_type");
|
||||
$unitKerja = $request->input("departement");
|
||||
$vehicle = $request->input("vehicle");
|
||||
$isActive = $request->input("isActive");
|
||||
|
||||
if ($request->ajax()) {
|
||||
$dataStiker = DB::table("transaksi_stiker as ts")
|
||||
->leftJoin("detail_transaksi_stiker as dts", "dts.notrans", "=", "ts.notrans")
|
||||
@@ -55,40 +68,47 @@ public function getMember(Request $request)
|
||||
jm.nama vehicle, dts.jenis_member, cm.no_card as no_card'),
|
||||
)
|
||||
->distinct();
|
||||
// ->select(DB::raw('ts.notrans as notrans , ts.nama , ts.alamat as alamat , ts.telepon as telepon , ts.awal as awal , ts.akhir as akhir, sk.nama as unit_kerja, jl.nama as jenis_member, ts.no_id'))
|
||||
|
||||
if ($request->nama) {
|
||||
$dataStiker = $dataStiker->where("ts.nama", "like", "%" . $request->nama . "%");
|
||||
if ($searchBy && $searchValue !== "") {
|
||||
switch ($searchBy) {
|
||||
case "nama":
|
||||
$nama = strtolower($searchValue);
|
||||
$NAMA = strtoupper($searchValue);
|
||||
$dataStiker->where("ts.nama", "ILIKE", "%{$searchValue}%");
|
||||
break;
|
||||
case "alamat":
|
||||
$dataStiker->where("ts.alamat", "like", "%{$searchValue}%");
|
||||
break;
|
||||
case "nopol":
|
||||
$dataStiker->where("dts.nopol", "like", "%{$searchValue}%");
|
||||
break;
|
||||
case "nocard":
|
||||
$dataStiker->where("cm.nocard", "like", "%{$searchValue}%");
|
||||
break;
|
||||
case "notrans":
|
||||
$dataStiker->where("ts.notrans", "like", "%{$searchValue}%");
|
||||
break;
|
||||
// case "":
|
||||
// $dataStiker->where("ts.nama", "like", "%{$searchValue}%");
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->notrans) {
|
||||
$dataStiker = $dataStiker->where("ts.notrans", "like", "%" . $request->notrans . "%");
|
||||
if ($memberType) {
|
||||
$dataStiker->where("ts.jenis_langganan", $memberType);
|
||||
}
|
||||
|
||||
if ($request->nopol) {
|
||||
$dataStiker = $dataStiker->where("ts.unit_kerja", "like", "%" . $request->depart . "%");
|
||||
if ($unitKerja) {
|
||||
$dataStiker->where("ts.unit_kerja", $unitKerja);
|
||||
}
|
||||
|
||||
if ($request->member) {
|
||||
$dataStiker = $dataStiker->where("ts.jenis_langganan", "like", "%" . $request->member . "%");
|
||||
if ($vehicle) {
|
||||
$dataStiker->where("dts.jenis_mobil", $vehicle);
|
||||
}
|
||||
|
||||
if ($request->nopol) {
|
||||
$dataStiker = $dataStiker->where("dts.nopol", "like", "%" . $request->nopol . "%");
|
||||
if ($request->input("isActive") == "1") {
|
||||
$dataStiker->whereRaw("NOW() BETWEEN ts.awal AND ts.akhir");
|
||||
}
|
||||
|
||||
if ($request->vehicle) {
|
||||
$dataStiker = $dataStiker->where("dts.jenis_mobil", "like", "%" . $request->vehicle . "%");
|
||||
}
|
||||
|
||||
if ($request->nocard) {
|
||||
$dataStiker = $dataStiker->where("cm.no_card", "like", "%" . $request->nocard . "%");
|
||||
}
|
||||
|
||||
if ($request->isactive === "1") {
|
||||
$dataStiker = $dataStiker->whereRaw("now() between ts.awal and ts.akhir");
|
||||
}
|
||||
|
||||
// Log::info($dataStiker->toSql());
|
||||
|
||||
$dataStiker = $dataStiker->get();
|
||||
@@ -132,22 +152,47 @@ public function checkField(Request $request)
|
||||
return response()->json(["response" => true, "message" => "Data sudah ada"]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
public function store(Request $request, MakeStikerServices $makeStiker)
|
||||
{
|
||||
Log::info("Data yang diterima : " . json_encode($request->all()));
|
||||
$mountYearNow = Carbon::now()->format("m/Y");
|
||||
|
||||
$dataStiker = $request->input("formData");
|
||||
$dataVehicle = $request->input("nopolData");
|
||||
$dataCard = $request->input("cardNumber");
|
||||
Log::info("Data Stiker : " . json_encode($dataStiker));
|
||||
Log::info("Data Kendaraan : " . json_encode($dataVehicle));
|
||||
Log::info("Data kartu : " . json_encode($dataCard));
|
||||
// $cleanedData = stripslashes(trim($data));
|
||||
// Log::debug('Modified : ' . json_encode($cleanedData));
|
||||
// $dataStiker = json_decode($cleanedData, false);
|
||||
// Log::info('Debuggind data : ' . json_encode($dataStiker));
|
||||
$getTrans = DB::table("indexnum")
|
||||
->whereIn("nama", ["TRX", "IDN"])
|
||||
->pluck("value", "nama");
|
||||
$noTrans = $getTrans->get("TRX");
|
||||
$noID = $getTrans->get("IDN");
|
||||
|
||||
// Log::info("Get Trans : " . json_encode($getTrans));
|
||||
// Log::info("No Trans : " . $noTrans);
|
||||
// Log::info("No ID : " . $noID);
|
||||
|
||||
$noTransFormat = str_pad($noTrans, 5, "0", STR_PAD_LEFT);
|
||||
$noIDFormat = str_pad($noID, 5, "0", STR_PAD_LEFT);
|
||||
|
||||
$getLocation = SoftSettings::first();
|
||||
Log::info("Namalokasi : " . json_encode($getLocation->namalokasi));
|
||||
$ignore = ["RS", "PT", "CV", "TBK"];
|
||||
$nama = preg_replace("/[^A-Za-z0-9 ]/", "", $getLocation->namalokasi);
|
||||
$kata = preg_split("/\s+/", trim($nama));
|
||||
$identity = "";
|
||||
foreach ($kata as $k) {
|
||||
if (in_array(strtoupper($k), $ignore)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$identity .= strtoupper($k[0]);
|
||||
}
|
||||
|
||||
$randomNumber = strtoupper(Str::random(6));
|
||||
|
||||
$newTrans = "TRX-" . $identity . "-" . Carbon::now()->format("Ymd-His") . "-" . $randomNumber;
|
||||
$newID = "IDN-" . $identity . "-" . Carbon::now()->format("Ymd-His") . "-" . $randomNumber;
|
||||
// $noid = $seqId->value . "-IDT-" . $mountYearNow;
|
||||
// $validate = Validator::make($request->all(),[
|
||||
// 'nama' => 'required|string|unique',
|
||||
// // 'nopol' => 'required|string|unique:detail_transaksi_stiker,nopol',
|
||||
@@ -158,84 +203,131 @@ public function store(Request $request)
|
||||
// return response()->json(['response' => false, 'message' => 'pastikan nama, Nomor Polisi, dan data kartu sudah terisi']);
|
||||
// }
|
||||
|
||||
$dateNow = Carbon::now()->format("Y-m-d H:m:s");
|
||||
$seqTrans = DB::table("indexnum")->select("value")->where("nama", "sticker")->first();
|
||||
$seqId = DB::table("indexnum")->select("value")->where("nama", "identitas")->first();
|
||||
// $dateNow = Carbon::now()->format("Y-m-d H:m:s");
|
||||
// $seqTrans = DB::table("indexnum")->select("value")->where("nama", "sticker")->first();
|
||||
// $seqId = DB::table("indexnum")->select("value")->where("nama", "identitas")->first();
|
||||
|
||||
$notrans = $seqTrans->value . "/STK/" . $mountYearNow;
|
||||
$noid = $seqId->value . "/IDT/" . $mountYearNow;
|
||||
$user = Auth::user();
|
||||
// $notrans = $seqTrans->value . "/STK/" . $mountYearNow;
|
||||
// $noid = $seqId->value . "/IDT/" . $mountYearNow;
|
||||
// $user = Auth::user();
|
||||
|
||||
$periode = explode(" - ", $dataStiker["periode"]);
|
||||
Log::info("Parcing Periode : " . json_encode($periode));
|
||||
$awal = Carbon::createFromFormat("d-m-Y H:i", $periode[0]);
|
||||
$akhir = Carbon::createFromFormat("d-m-Y H:i", $periode[1]);
|
||||
// // Log::info($user);
|
||||
|
||||
$dataStiker = $request->input("formData");
|
||||
$dataVehicle = $request->input("nopolData");
|
||||
$dataCard = $request->input("cardNumber");
|
||||
Log::info("Data Stiker : " . json_encode($dataStiker));
|
||||
Log::info("Data Kendaraan : " . json_encode($dataVehicle));
|
||||
Log::info("Data kartu : " . json_encode($dataCard));
|
||||
|
||||
if ($dataStiker["periode"]) {
|
||||
$periode = explode(" - ", $dataStiker["periode"]);
|
||||
Log::info("Parcing Periode : " . json_encode($periode));
|
||||
$awal = Carbon::createFromFormat("d-m-Y H:i", $periode[0]);
|
||||
$akhir = Carbon::createFromFormat("d-m-Y H:i", $periode[1]);
|
||||
} else {
|
||||
$awal = Carbon::createFromFormat("d-m-Y H:i", $dataStiker["awal"]);
|
||||
$akhir = Carbon::createFromFormat("d-m-Y H:i", $dataStiker["akhir"]);
|
||||
}
|
||||
Log::info("Awal : " . $awal . " Akhir : " . $akhir);
|
||||
// Log::info($user);
|
||||
|
||||
try {
|
||||
$dataStiker = [
|
||||
"jenis_transaksi" => $dataStiker["jenis_transaksi"], // 0 = transaksi baru , 1 = perpanjangan
|
||||
"notrans" => $notrans,
|
||||
"no_id" => $noid,
|
||||
"nama" => $dataStiker["nama"],
|
||||
"alamat" => $dataStiker["address"] ?? "",
|
||||
"telepon" => $dataStiker["phone"] ?? "",
|
||||
"unit_kerja" => $dataStiker["depart"],
|
||||
"jenis_stiker" => $dataStiker["member"],
|
||||
"awal" => $awal,
|
||||
"akhir" => $akhir,
|
||||
"harga" => $dataStiker["harga"] ?? 0,
|
||||
"keterangan" => $dataStiker["note"] ?? "",
|
||||
"tanggal" => $dateNow,
|
||||
"operator" => $user->nomer,
|
||||
];
|
||||
$dataStiker["notrans"] = $newTrans;
|
||||
$dataStiker["no_id"] = $newID;
|
||||
$dataStiker["awal"] = $awal;
|
||||
$dataStiker["akhir"] = $akhir;
|
||||
|
||||
DB::table("transaksi_stiker")->insert($dataStiker);
|
||||
|
||||
if ($dataVehicle) {
|
||||
foreach ($dataVehicle as $nopol) {
|
||||
$dataVehicle = [
|
||||
"notrans" => $notrans,
|
||||
"nopol" => $nopol["nopol"],
|
||||
"jenis_mobil" => $nopol["vehicle"],
|
||||
"jenis_member" => $nopol["member"],
|
||||
"merk" => $nopol["merk"],
|
||||
];
|
||||
DB::table("detail_transaksi_stiker")->insert($dataVehicle);
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
if (!empty($dataVehicle)) {
|
||||
foreach ($dataVehicle as &$vehicle) {
|
||||
$vehicle["notrans"] = $newTrans;
|
||||
}
|
||||
|
||||
if ($dataCard) {
|
||||
foreach ($dataCard as $cardNumber) {
|
||||
$dataCard = [
|
||||
"notrans" => $noid,
|
||||
"no_card" => $cardNumber["nocard"],
|
||||
"no_urut" => $cardNumber["nourut"],
|
||||
];
|
||||
|
||||
DB::table("card_member")->insert($dataCard);
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DB::table("indexnum")
|
||||
->where("nama", "sticker")
|
||||
->update(["value" => DB::raw("lpad(to_number(value,'9999')+1)::text, 4, '0')")]);
|
||||
DB::table("indexnum")
|
||||
->where("nama", "identitas")
|
||||
->update(["value" => DB::raw("lpad(to_number(value,'9999')+1)::text, 4, '0')")]);
|
||||
$response = true;
|
||||
$msg = "Data berhasil di simpan";
|
||||
} catch (Exception $e) {
|
||||
$response = false;
|
||||
$msg = "Gagal menyimpan data " . $e->getMessage() . $e->getLine();
|
||||
}
|
||||
|
||||
return response()->json(["response" => $response, "pesan" => $msg]);
|
||||
if (!empty($dataCard)) {
|
||||
foreach ($dataCard as &$cardNumber) {
|
||||
$cardNumber["notrans"] = $newID;
|
||||
}
|
||||
}
|
||||
|
||||
$createData = $makeStiker->stikerCreate(
|
||||
[
|
||||
"dataSticker" => $dataStiker,
|
||||
"dataVehicle" => $dataVehicle ?? null,
|
||||
"dataCard" => $dataCard ?? null,
|
||||
],
|
||||
$awal,
|
||||
$akhir,
|
||||
);
|
||||
|
||||
Log::info("Status penyimpanan : " . $createData);
|
||||
|
||||
// try {
|
||||
// $dataStiker = [
|
||||
// "jenis_transaksi" => $dataStiker["jenis_transaksi"], // 0 = transaksi baru , 1 = perpanjangan
|
||||
// "notrans" => $notrans,
|
||||
// "no_id" => $noid,
|
||||
// "nama" => $dataStiker["nama"],
|
||||
// "alamat" => $dataStiker["address"] ?? "",
|
||||
// "telepon" => $dataStiker["phone"] ?? "",
|
||||
// "unit_kerja" => $dataStiker["depart"],
|
||||
// "jenis_stiker" => $dataStiker["member"],
|
||||
// "awal" => $awal,
|
||||
// "akhir" => $akhir,
|
||||
// "harga" => $dataStiker["harga"] ?? 0,
|
||||
// "keterangan" => $dataStiker["note"] ?? "",
|
||||
// "tanggal" => $dateNow,
|
||||
// "operator" => $user->nomer,
|
||||
// ];
|
||||
|
||||
// DB::table("transaksi_stiker")->insert($dataStiker);
|
||||
|
||||
// if ($dataVehicle) {
|
||||
// foreach ($dataVehicle as $nopol) {
|
||||
// $dataVehicle = [
|
||||
// "notrans" => $notrans,
|
||||
// "nopol" => $nopol["nopol"],
|
||||
// "jenis_mobil" => $nopol["vehicle"],
|
||||
// "jenis_member" => $nopol["member"],
|
||||
// "merk" => $nopol["merk"],
|
||||
// ];
|
||||
// DB::table("detail_transaksi_stiker")->insert($dataVehicle);
|
||||
// }
|
||||
// } else {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// if ($dataCard) {
|
||||
// foreach ($dataCard as $cardNumber) {
|
||||
// $dataCard = [
|
||||
// "notrans" => $noid,
|
||||
// "no_card" => $cardNumber["nocard"],
|
||||
// "no_urut" => $cardNumber["nourut"],
|
||||
// ];
|
||||
|
||||
// DB::table("card_member")->insert($dataCard);
|
||||
// }
|
||||
// } else {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// DB::table("indexnum")
|
||||
// ->where("nama", "sticker")
|
||||
// ->update(["value" => DB::raw("lpad(to_number(value,'9999')+1)::text, 4, '0')")]);
|
||||
// DB::table("indexnum")
|
||||
// ->where("nama", "identitas")
|
||||
// ->update(["value" => DB::raw("lpad(to_number(value,'9999')+1)::text, 4, '0')")]);
|
||||
// $response = true;
|
||||
// $msg = "Data berhasil di simpan";
|
||||
// } catch (Exception $e) {
|
||||
// $response = false;
|
||||
// $msg = "Gagal menyimpan data " . $e->getMessage() . $e->getLine();
|
||||
// }
|
||||
|
||||
return $createData;
|
||||
// return response()->json([
|
||||
// // "response" => $response,
|
||||
// "response" => $createData,
|
||||
// "pesan" => $createData,
|
||||
// ]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,8 +339,9 @@ public function store(Request $request)
|
||||
public function show($id)
|
||||
{
|
||||
Log::info("Data yang diterima : " . json_encode($id));
|
||||
$dataStiker = StikerTrans::with("stiker_details.vehicle", "memberCard")
|
||||
->select(
|
||||
$dataStiker = StikerTrans
|
||||
// with("stiker_details.vehicle", "memberCard")
|
||||
::select(
|
||||
"transaksi_stiker.notrans",
|
||||
"transaksi_stiker.nama",
|
||||
"transaksi_stiker.alamat",
|
||||
@@ -258,13 +351,31 @@ public function show($id)
|
||||
"transaksi_stiker.jenis_langganan",
|
||||
"transaksi_stiker.unit_kerja",
|
||||
"transaksi_stiker.no_id",
|
||||
"transaksi_stiker.harga",
|
||||
"jl.nama as jmember",
|
||||
"sk.nama as dept",
|
||||
// "detail_transaksi_stiker.nama",
|
||||
// "detail_transaksi_stiker.tarif",
|
||||
)
|
||||
->leftJoin("jenis_langganan as jl", "jl.id", "=", "transaksi_stiker.jenis_langganan")
|
||||
->leftJoin("stasiunkerja as sk", "sk.kode", "=", "transaksi_stiker.unit_kerja")
|
||||
->where("notrans", "like", "%" . $id . "%")
|
||||
->first();
|
||||
|
||||
$vehicleDetails = StikerTransDetail::query()
|
||||
->from("detail_transaksi_stiker as dts")
|
||||
->select("jm.nama as vehicle", "ts.tarif", "dts.*")
|
||||
->leftJoin("jenis_mobil as jm", "dts.jenis_mobil", "=", "jm.id")
|
||||
->leftJoin("tarif_stiker as ts", function ($join) {
|
||||
$join->on("dts.jenis_member", "=", "ts.jenis_langganan")->on("dts.jenis_mobil", "=", "ts.id_mobil");
|
||||
})
|
||||
->where("notrans", $dataStiker->notrans)
|
||||
->get();
|
||||
|
||||
$cardMember = MemberCard::where("notrans", $dataStiker->no_id)->get();
|
||||
|
||||
$dataStiker["stiker_details"] = $vehicleDetails;
|
||||
$dataStiker["memberCard"] = $cardMember;
|
||||
// $dataStiker = DB::table('transaksi_stiker as ts')
|
||||
// ->leftjoin('detail_transaksi_stiker as dts','dts.notrans','=','ts.notrans')
|
||||
// ->leftJoin('jenis_langganan as jl','jl.id','=','ts.jenis_langganan')
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class TransaksiParkirController extends Controller
|
||||
{
|
||||
@@ -17,6 +19,118 @@ public function index()
|
||||
return view ('operasional.transaksi-parkir');
|
||||
}
|
||||
|
||||
/**
|
||||
* Data transaksi parkir dengan filter pencarian.
|
||||
*
|
||||
* Filter (semua opsional):
|
||||
* - field: id | no_pol | no_barcode, + q: kata kunci
|
||||
* - tgl_awal / tgl_akhir (Y-m-d): periode kolom tanggal
|
||||
* - status_kendaraan: 1 = masuk, 0 = keluar
|
||||
* - status_transaksi: 0 = casual, 3 = member, 32 = denda
|
||||
* - export=csv: unduh hasil filter sebagai CSV
|
||||
*/
|
||||
public function data(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'field' => 'nullable|in:id,no_pol,no_barcode',
|
||||
'q' => 'nullable|string|max:100',
|
||||
'tgl_awal' => 'nullable|date_format:Y-m-d',
|
||||
'tgl_akhir' => 'nullable|date_format:Y-m-d|after_or_equal:tgl_awal',
|
||||
'status_kendaraan' => 'nullable|in:0,1',
|
||||
'status_transaksi' => 'nullable|in:0,3,32',
|
||||
'per_page' => 'nullable|integer|min:1|max:500',
|
||||
]);
|
||||
|
||||
$query = $this->filteredQuery($request);
|
||||
|
||||
if ($request->query('export') === 'csv') {
|
||||
return $this->exportCsv($query);
|
||||
}
|
||||
|
||||
$perPage = (int) $request->input('per_page', 50);
|
||||
$rows = $query->paginate($perPage);
|
||||
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'data' => $rows->items(),
|
||||
'meta' => [
|
||||
'current_page' => $rows->currentPage(),
|
||||
'per_page' => $rows->perPage(),
|
||||
'total' => $rows->total(),
|
||||
'last_page' => $rows->lastPage(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function filteredQuery(Request $request)
|
||||
{
|
||||
$query = DB::table('transaksi_parkir as tp')
|
||||
->leftJoin('jenis_mobil as jm', 'jm.id', '=', 'tp.id_kendaraan')
|
||||
->select(
|
||||
'tp.id',
|
||||
'tp.no_pol',
|
||||
'tp.no_barcode',
|
||||
'tp.id_kendaraan',
|
||||
'jm.nama as nama_kendaraan',
|
||||
'tp.status',
|
||||
'tp.status_transaksi',
|
||||
'tp.waktu_masuk',
|
||||
'tp.waktu_keluar',
|
||||
'tp.tanggal'
|
||||
);
|
||||
|
||||
// 1. Pencarian: id / no_pol / no_barcode
|
||||
if ($request->filled('q')) {
|
||||
$field = $request->input('field', 'id');
|
||||
$query->where("tp.{$field}", 'ILIKE', '%' . $request->input('q') . '%');
|
||||
}
|
||||
|
||||
// 2. Periode awal - akhir (kolom tanggal)
|
||||
if ($request->filled('tgl_awal')) {
|
||||
$query->whereDate('tp.tanggal', '>=', $request->input('tgl_awal'));
|
||||
}
|
||||
if ($request->filled('tgl_akhir')) {
|
||||
$query->whereDate('tp.tanggal', '<=', $request->input('tgl_akhir'));
|
||||
}
|
||||
|
||||
// 3. Status kendaraan: 1 = masuk, 0 = keluar
|
||||
if ($request->filled('status_kendaraan')) {
|
||||
$query->where('tp.status', (int) $request->input('status_kendaraan'));
|
||||
}
|
||||
|
||||
// 4. Status transaksi: 0 = casual, 3 = member, 32 = denda
|
||||
if ($request->filled('status_transaksi')) {
|
||||
$query->where('tp.status_transaksi', (int) $request->input('status_transaksi'));
|
||||
}
|
||||
|
||||
return $query->orderBy('tp.tanggal', 'desc');
|
||||
}
|
||||
|
||||
protected function exportCsv($query): StreamedResponse
|
||||
{
|
||||
$filename = 'transaksi-parkir-' . now()->format('Ymd-His') . '.csv';
|
||||
|
||||
return response()->streamDownload(function () use ($query) {
|
||||
$out = fopen('php://output', 'w');
|
||||
fputcsv($out, ['ID', 'No. Pol', 'Barcode', 'Kendaraan', 'Status Kendaraan', 'Status Transaksi', 'Waktu Masuk', 'Waktu Keluar']);
|
||||
$query->chunk(1000, function ($rows) use ($out) {
|
||||
foreach ($rows as $r) {
|
||||
fputcsv($out, [
|
||||
$r->id,
|
||||
$r->no_pol,
|
||||
$r->no_barcode,
|
||||
trim(($r->id_kendaraan ?? '') . ' ' . ($r->nama_kendaraan ?? '')),
|
||||
$r->status,
|
||||
$r->status_transaksi,
|
||||
$r->waktu_masuk,
|
||||
$r->waktu_keluar,
|
||||
]);
|
||||
}
|
||||
});
|
||||
fclose($out);
|
||||
}, $filename, ['Content-Type' => 'text/csv']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
|
||||
@@ -1,999 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Parking;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
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");
|
||||
}
|
||||
|
||||
// private function transaksiParkir($isMirror)
|
||||
// {
|
||||
// $mirror = DB::table('parkir_transaksi')
|
||||
// $query = DB::table('transaksi_parkir');
|
||||
|
||||
// return $table;
|
||||
// }
|
||||
|
||||
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))
|
||||
|
||||
// 🔹 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"),
|
||||
};
|
||||
})
|
||||
|
||||
// 🔹 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)
|
||||
{
|
||||
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 = "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");
|
||||
|
||||
// $dateColumn = $harian == 1
|
||||
// ? 'tp.waktu_keluar'
|
||||
// : 'tp.pklogin';
|
||||
if ($harian == 1) {
|
||||
$isReport = "harian";
|
||||
// $dateColumn = ["tp.waktu_keluar"];
|
||||
$dateColumn = ["tp.waktu_masuk", "tp.waktu_keluar"];
|
||||
} else {
|
||||
$isReport = "shift";
|
||||
// $dateColumn = ["tp.pklogin"];
|
||||
$dateColumn = ["tp.pmlogin", "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) use ($startDate, $endDate) {
|
||||
$start = $startDate . " 00:00:00";
|
||||
$end = $endDate . " 00:00:00";
|
||||
// ======================
|
||||
// PISAH MASUK & KELUAR
|
||||
// ======================
|
||||
// $masuk = $items;
|
||||
$masuk = $items->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true));
|
||||
|
||||
// $masuk = $items->where("status", 1);
|
||||
// ->whereBetween("waktu_masuk", [$startDate . " 00:00:00", $endDate . " 23:59:59"]);
|
||||
// ->filter(function ($item) use ($start, $end) {
|
||||
// $waktuMasuk = $item->waktu_masuk;
|
||||
// $pmLogin = $item->pmlogin ?? null;
|
||||
|
||||
// $inWaktuMasuk = $waktuMasuk && $waktuMasuk >= $start && $waktuMasuk <= $end;
|
||||
// $inPmMasuk = $pmLogin && $pmLogin >= $start && $pmLogin <= $end;
|
||||
|
||||
// return $inWaktuMasuk || $inPmMasuk;
|
||||
// });
|
||||
// $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" => $masuk->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);
|
||||
$masuk = $items->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true));
|
||||
// $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;
|
||||
$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" => $masuk->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 [
|
||||
// 'date' => $startDate->format('Y-m-d'),÷
|
||||
"date" => $startDate,
|
||||
"reportTime" => $isReport,
|
||||
"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]);
|
||||
})
|
||||
// ->whereNull("id_op_masuk")
|
||||
// ->where("manual", 1)
|
||||
// ->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("petugas")
|
||||
->groupBy("id_op_keluar")
|
||||
->map(function ($items, $id_op_keluar) {
|
||||
// ======================
|
||||
// PISAH MASUK & KELUAR
|
||||
// ======================
|
||||
// $masuk = $items->where('status', 1);
|
||||
$masuk = $items->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true));
|
||||
// $keluar = $items->where('status', 0);
|
||||
$keluar = $items->filter(fn($r) => (int) $r->status === 0);
|
||||
// $tunai = $keluar->where('cara_bayar', '!=', 3);
|
||||
|
||||
// ======================
|
||||
// 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');
|
||||
$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");
|
||||
|
||||
// ======================
|
||||
// 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" => 0,
|
||||
"tunaiOut" => $tunai->count(),
|
||||
// ========= MASUK =========
|
||||
"masuk" => [
|
||||
"casual" => [
|
||||
"jumlah" => 0,
|
||||
"income" => $masuk->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);
|
||||
$masuk = $items->filter(fn($row) => in_array(data_get($row, "cara_bayar"), [null, 0, "0"], true));
|
||||
// $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" => 0,
|
||||
"nonTunaiOut" => $nonTunai->count(),
|
||||
|
||||
// ========= MASUK =========
|
||||
"masuk" => [
|
||||
"casual" => [
|
||||
"jumlah" => 0,
|
||||
"income" => $masuk->sum("bayar_masuk"),
|
||||
],
|
||||
"member" => [
|
||||
"jumlah" => $masuk->count(),
|
||||
"income" => $masuk->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"];
|
||||
$dateColumn = ["tp.waktu_masuk", "tp.waktu_keluar"];
|
||||
} else {
|
||||
// $dateColumn = ["tp.pklogin"];
|
||||
$dateColumn = ["tp.pmlogin", "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(),
|
||||
"masuk" => [
|
||||
"casual" => [
|
||||
"jumlah" => 0,
|
||||
"income" => 0,
|
||||
],
|
||||
],
|
||||
"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(),
|
||||
"masuk" => [
|
||||
"casual" => [
|
||||
"jumlah" => 0,
|
||||
"income" => 0,
|
||||
],
|
||||
],
|
||||
"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 ===============///
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Parking\Setup\Gate;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\Parking\NetworkService;
|
||||
use App\Models\ConfigPosNetwork;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class MasterConfigNetworkController extends Controller
|
||||
{
|
||||
public function index(NetworkService $dhcp)
|
||||
{
|
||||
$reservations = ConfigPosNetwork::orderBy("hostname")->get();
|
||||
|
||||
$dhcpStatus = $dhcp->status();
|
||||
|
||||
return view("setup.index", compact("reservations", "dhcpStatus"));
|
||||
}
|
||||
|
||||
public function status(NetworkService $dhcp)
|
||||
{
|
||||
return response()->json($dhcp->status());
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
"hostname" => ["required", "string", "max:100", 'regex:/^[a-zA-Z0-9_-]+$/'],
|
||||
|
||||
"mac_address" => ["required", "string", 'regex:/^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/'],
|
||||
|
||||
"ip_address" => ["required", "ip"],
|
||||
|
||||
"enabled" => ["nullable", "boolean"],
|
||||
]);
|
||||
|
||||
$data["mac_address"] = strtoupper($data["mac_address"]);
|
||||
|
||||
$data["enabled"] = $request->boolean("enabled");
|
||||
|
||||
// Cek duplicate MAC
|
||||
if (ConfigPosNetwork::where("mac_address", $data["mac_address"])->exists()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "MAC address already registered.",
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
// Cek duplicate IP
|
||||
if (ConfigPosNetwork::where("ip_address", $data["ip_address"])->exists()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "IP address already registered.",
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$reservation = ConfigPosNetwork::create($data);
|
||||
|
||||
return response()->json(
|
||||
[
|
||||
"success" => true,
|
||||
"message" => "DHCP reservation created successfully.",
|
||||
"data" => $reservation,
|
||||
],
|
||||
201,
|
||||
);
|
||||
}
|
||||
|
||||
public function update(Request $request, ConfigPosNetwork $reservation)
|
||||
{
|
||||
$data = $request->validate([
|
||||
"hostname" => ["required", "string", "max:100", 'regex:/^[a-zA-Z0-9_-]+$/'],
|
||||
|
||||
"mac_address" => ["required", "string", 'regex:/^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/'],
|
||||
|
||||
"ip_address" => ["required", "ip"],
|
||||
|
||||
"enabled" => ["nullable", "boolean"],
|
||||
]);
|
||||
|
||||
$data["mac_address"] = strtoupper($data["mac_address"]);
|
||||
|
||||
$data["enabled"] = $request->boolean("enabled");
|
||||
|
||||
// Cek duplicate MAC,
|
||||
// kecuali reservation yang sedang diedit
|
||||
if (
|
||||
ConfigPosNetwork::where("mac_address", $data["mac_address"])->where("id", "!=", $reservation->id)->exists()
|
||||
) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "MAC address already registered.",
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
// Cek duplicate IP
|
||||
if (ConfigPosNetwork::where("ip_address", $data["ip_address"])->where("id", "!=", $reservation->id)->exists()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "IP address already registered.",
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$reservation->update($data);
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "DHCP reservation updated successfully.",
|
||||
"data" => $reservation->fresh(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(ConfigPosNetwork $reservation)
|
||||
{
|
||||
$reservation->delete();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "Reservation deleted successfully.",
|
||||
]);
|
||||
}
|
||||
|
||||
public function test(NetworkService $dhcp)
|
||||
{
|
||||
try {
|
||||
$result = $dhcp->test();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "DHCP configuration is valid.",
|
||||
"data" => $result,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => $e->getMessage(),
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function apply(NetworkService $dhcp)
|
||||
{
|
||||
try {
|
||||
$dhcp->apply();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "DHCP configuration applied successfully.",
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => $e->getMessage(),
|
||||
],
|
||||
500,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function logs(NetworkService $dhcp)
|
||||
{
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"logs" => $dhcp->logs(30),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ConfigHardware;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class MasterGateHardwareController extends Controller
|
||||
{
|
||||
@@ -48,9 +47,11 @@ public function store(Request $request)
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
Log::info($id);
|
||||
// # ambil konfigurasi hardware berdasarkan id_pos (id pintu)
|
||||
$gateDetails = ConfigHardware::where('id_pos', $id)->first();
|
||||
return $gateDetails;
|
||||
|
||||
// # kalau belum ada datanya, kembalikan objek kosong biar form tetap kebuka
|
||||
return response()->json($gateDetails ?? (object) []);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,8 +74,26 @@ public function edit($id)
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
Log::info($id);
|
||||
Log::info($request->all());
|
||||
// # hanya kolom yang terdaftar di fillable yang boleh disimpan
|
||||
$allowed = (new ConfigHardware())->getFillable();
|
||||
$data = $request->input('data', []);
|
||||
|
||||
$filtered = [];
|
||||
foreach ((array) $data as $key => $value) {
|
||||
if (in_array($key, $allowed, true)) {
|
||||
// # ubah string kosong jadi null biar cocok dengan kolom integer
|
||||
$filtered[$key] = $value === '' ? null : $value;
|
||||
}
|
||||
}
|
||||
|
||||
// # simpan (buat baru kalau id_pos belum punya baris hardware)
|
||||
$hardware = ConfigHardware::updateOrCreate(['id_pos' => $id], $filtered);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Konfigurasi hardware berhasil disimpan.',
|
||||
'data' => $hardware,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Parking\Setup\Member;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use App\Models\Origin\MasterTarifStiker;
|
||||
use App\Models\Origin\MasterStasiunKerja;
|
||||
use App\Models\Origin\MasterJenisLangganan;
|
||||
|
||||
class MasterTarifStikerController extends Controller
|
||||
{
|
||||
/**
|
||||
* Halaman utama. Data dropdown (stasiun kerja & jenis langganan)
|
||||
* di-load langsung di sini biar gak perlu request tambahan pas modal dibuka.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$stasiunKerjaList = MasterStasiunKerja::orderBy("kode")->get(["kode", "nama"]);
|
||||
$jenisLanggananList = MasterJenisLangganan::orderBy("id")->get(["id", "nama"]);
|
||||
|
||||
return view("Parking.setup.member.tarifstiker", compact("stasiunKerjaList", "jenisLanggananList"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambil seluruh data tarif stiker, sekalian join nama stasiun kerja
|
||||
* biar gak perlu N+1 query pas render tabel.
|
||||
*/
|
||||
public function data(): JsonResponse
|
||||
{
|
||||
$data = MasterTarifStiker::with(["stasiunKerja:kode,nama"])
|
||||
->orderByDesc("tarif_id")
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"data" => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambil satu data berdasarkan tarif_id.
|
||||
*/
|
||||
public function show(string $tarif_id): JsonResponse
|
||||
{
|
||||
$item = MasterTarifStiker::with(["stasiunKerja:kode,nama"])->find($tarif_id);
|
||||
|
||||
if (!$item) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Data tarif stiker tidak ditemukan.",
|
||||
],
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"data" => $item,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpan data tarif stiker baru.
|
||||
* tarif_id tidak wajib diisi dari form — kalau kosong, di-generate
|
||||
* otomatis (max(tarif_id) + 1) karena tabel ini tidak punya
|
||||
* auto-increment/serial asli di database.
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
"tarif_id" => ["nullable", "integer", "unique:tarif_stiker,tarif_id"],
|
||||
"id_mobil" => ["required", "string", "max:10"],
|
||||
"jenis_langganan" => ["required", "string", "max:50"],
|
||||
"tarif" => ["required", "numeric"],
|
||||
"last_member" => ["nullable", "string", "max:5"],
|
||||
"tgl_akhir" => ["nullable", "string", "max:2"],
|
||||
"jenis" => ["nullable", "string", "max:30"],
|
||||
"jenis_member" => ["nullable", "string", "max:50"],
|
||||
"hitung_awal_bulan" => ["nullable", "integer"],
|
||||
"available_online" => ["nullable", "boolean"],
|
||||
"langganan" => ["nullable", "string", "max:32", "exists:stasiunkerja,kode"],
|
||||
"kode_akses" => ["nullable", "string", "max:5"],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Validasi gagal.",
|
||||
"errors" => $validator->errors(),
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$payload = $validator->validated();
|
||||
$payload["available_online"] = $request->boolean("available_online");
|
||||
|
||||
// Transaksi + lock untuk menghindari race condition kalau
|
||||
// ada 2 request bersamaan sama-sama generate tarif_id baru.
|
||||
$item = DB::transaction(function () use ($payload) {
|
||||
if (empty($payload["tarif_id"])) {
|
||||
$maxId = MasterTarifStiker::lockForUpdate()->max("tarif_id");
|
||||
$payload["tarif_id"] = ($maxId ?? 0) + 1;
|
||||
}
|
||||
|
||||
return MasterTarifStiker::create($payload);
|
||||
});
|
||||
|
||||
$item->load("stasiunKerja:kode,nama");
|
||||
|
||||
return response()->json(
|
||||
[
|
||||
"success" => true,
|
||||
"message" => "Data tarif stiker berhasil ditambahkan.",
|
||||
"data" => $item,
|
||||
],
|
||||
201,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perbarui data tarif stiker berdasarkan tarif_id.
|
||||
*/
|
||||
public function update(Request $request, string $tarif_id): JsonResponse
|
||||
{
|
||||
$item = MasterTarifStiker::find($tarif_id);
|
||||
|
||||
if (!$item) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Data tarif stiker tidak ditemukan.",
|
||||
],
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
"id_mobil" => ["required", "string", "max:10"],
|
||||
"jenis_langganan" => ["required", "string", "max:50"],
|
||||
"tarif" => ["required", "numeric"],
|
||||
"last_member" => ["nullable", "string", "max:5"],
|
||||
"tgl_akhir" => ["nullable", "string", "max:2"],
|
||||
"jenis" => ["nullable", "string", "max:30"],
|
||||
"jenis_member" => ["nullable", "string", "max:50"],
|
||||
"hitung_awal_bulan" => ["nullable", "integer"],
|
||||
"available_online" => ["nullable", "boolean"],
|
||||
"langganan" => ["nullable", "string", "max:32", "exists:stasiunkerja,kode"],
|
||||
"kode_akses" => ["nullable", "string", "max:5"],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Validasi gagal.",
|
||||
"errors" => $validator->errors(),
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$payload = $validator->validated();
|
||||
$payload["available_online"] = $request->boolean("available_online");
|
||||
|
||||
$item->update($payload);
|
||||
$item->load("stasiunKerja:kode,nama");
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "Data tarif stiker berhasil diperbarui.",
|
||||
"data" => $item,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hapus data tarif stiker berdasarkan tarif_id.
|
||||
*/
|
||||
public function destroy(string $tarif_id): JsonResponse
|
||||
{
|
||||
$item = MasterTarifStiker::find($tarif_id);
|
||||
|
||||
if (!$item) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Data tarif stiker tidak ditemukan.",
|
||||
],
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
$item->delete();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "Data tarif stiker berhasil dihapus.",
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Parking\Setup\Member;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Origin\MasterStasiunKerja;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StasiunKerjaController extends Controller
|
||||
{
|
||||
/**
|
||||
* Tampilkan halaman utama (view + tabel kosong, data di-load via JS).
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view("Parking.setup.member.stasiunkerja");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambil seluruh data stasiun kerja dalam format JSON.
|
||||
* Dipanggil via fetch() dari JS untuk mengisi tabel.
|
||||
*/
|
||||
public function data(): JsonResponse
|
||||
{
|
||||
$data = MasterStasiunKerja::orderBy("kode")->get();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"data" => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambil satu data berdasarkan kode (dipakai saat buka form edit).
|
||||
*/
|
||||
public function show(string $kode): JsonResponse
|
||||
{
|
||||
$item = MasterStasiunKerja::find($kode);
|
||||
|
||||
if (!$item) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Data stasiun kerja tidak ditemukan.",
|
||||
],
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"data" => $item,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpan data stasiun kerja baru.
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
"kode" => ["required", "string", "max:50", Rule::unique("stasiunkerja", "kode")],
|
||||
"nama" => ["required", "string", "max:255"],
|
||||
"margin" => ["nullable", "integer"],
|
||||
"spv" => ["nullable", "string", "max:20"],
|
||||
"target" => ["nullable", "integer"],
|
||||
"id_lokasi" => ["nullable", "string", "max:10"],
|
||||
"lantai" => ["nullable", "string", "max:4"],
|
||||
"status" => ["nullable", "integer"],
|
||||
"alamat" => ["nullable", "string", "max:255"],
|
||||
"bank" => ["nullable", "string", "max:64"],
|
||||
"telp" => ["nullable", "string", "max:32"],
|
||||
"kode_akses" => ["nullable", "string", "max:5"],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Validasi gagal.",
|
||||
"errors" => $validator->errors(),
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$item = MasterStasiunKerja::create($validator->validated());
|
||||
|
||||
return response()->json(
|
||||
[
|
||||
"success" => true,
|
||||
"message" => "Data stasiun kerja berhasil ditambahkan.",
|
||||
"data" => $item,
|
||||
],
|
||||
201,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perbarui data stasiun kerja berdasarkan kode.
|
||||
*/
|
||||
public function update(Request $request, string $kode): JsonResponse
|
||||
{
|
||||
$item = MasterStasiunKerja::find($kode);
|
||||
|
||||
if (!$item) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Data stasiun kerja tidak ditemukan.",
|
||||
],
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
"nama" => ["required", "string", "max:255"],
|
||||
"margin" => ["nullable", "integer"],
|
||||
"spv" => ["nullable", "string", "max:20"],
|
||||
"target" => ["nullable", "integer"],
|
||||
"id_lokasi" => ["nullable", "string", "max:10"],
|
||||
"lantai" => ["nullable", "string", "max:4"],
|
||||
"status" => ["nullable", "integer"],
|
||||
"alamat" => ["nullable", "string", "max:255"],
|
||||
"bank" => ["nullable", "string", "max:64"],
|
||||
"telp" => ["nullable", "string", "max:32"],
|
||||
"kode_akses" => ["nullable", "string", "max:5"],
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Validasi gagal.",
|
||||
"errors" => $validator->errors(),
|
||||
],
|
||||
422,
|
||||
);
|
||||
}
|
||||
|
||||
$item->update($validator->validated());
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "Data stasiun kerja berhasil diperbarui.",
|
||||
"data" => $item,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hapus data stasiun kerja berdasarkan kode.
|
||||
*/
|
||||
public function destroy(string $kode): JsonResponse
|
||||
{
|
||||
$item = MasterStasiunKerja::find($kode);
|
||||
|
||||
if (!$item) {
|
||||
return response()->json(
|
||||
[
|
||||
"success" => false,
|
||||
"message" => "Data stasiun kerja tidak ditemukan.",
|
||||
],
|
||||
404,
|
||||
);
|
||||
}
|
||||
|
||||
$item->delete();
|
||||
|
||||
return response()->json([
|
||||
"success" => true,
|
||||
"message" => "Data stasiun kerja berhasil dihapus.",
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\VehicleItem;
|
||||
use App\Models\MasterTarif;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class MasterVehicleController extends Controller
|
||||
{
|
||||
@@ -40,7 +42,38 @@ public function create()
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
$request->merge([
|
||||
'id' => strtoupper((string) $request->input('id')),
|
||||
'short_cut' => strtoupper((string) $request->input('short_cut')),
|
||||
]);
|
||||
|
||||
$data = $request->validate([
|
||||
'id' => 'required|string|max:16|alpha_num|unique:jenis_mobil,id',
|
||||
'nama' => 'required|string|max:100',
|
||||
'short_cut' => 'required|string|max:16',
|
||||
'tarif' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$vehicle = DB::transaction(function () use ($data) {
|
||||
$vehicle = VehicleItem::create([
|
||||
'id' => strtoupper($data['id']),
|
||||
'nama' => $data['nama'],
|
||||
'short_cut' => strtoupper($data['short_cut']),
|
||||
'tanggal' => now(),
|
||||
'orang' => 0,
|
||||
'validasi' => 0,
|
||||
]);
|
||||
|
||||
MasterTarif::create([
|
||||
'id_mobil' => $vehicle->id,
|
||||
'tarif' => $data['tarif'],
|
||||
'tanggal' => now(),
|
||||
]);
|
||||
|
||||
return $vehicle;
|
||||
});
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Jenis kendaraan dan tarif awal berhasil ditambahkan.', 'data' => $vehicle], 201);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +84,10 @@ public function store(Request $request)
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
$vehicle = VehicleItem::findOrFail($id);
|
||||
$tarif = MasterTarif::find($id);
|
||||
|
||||
return response()->json(['success' => true, 'data' => $vehicle, 'tarif' => $tarif]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +98,7 @@ public function show($id)
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
return response()->json(['success' => true, 'data' => VehicleItem::findOrFail($id)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +110,18 @@ public function edit($id)
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
$data = $request->validate([
|
||||
'nama' => 'required|string|max:100',
|
||||
'short_cut' => 'required|string|max:16',
|
||||
]);
|
||||
|
||||
$vehicle = VehicleItem::findOrFail($id);
|
||||
$vehicle->update([
|
||||
'nama' => $data['nama'],
|
||||
'short_cut' => strtoupper($data['short_cut']),
|
||||
]);
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Jenis kendaraan berhasil diperbarui.', 'data' => $vehicle]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,6 +132,11 @@ public function update(Request $request, $id)
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
DB::transaction(function () use ($id) {
|
||||
MasterTarif::where('id_mobil', $id)->delete();
|
||||
VehicleItem::findOrFail($id)->delete();
|
||||
});
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Jenis kendaraan dan tarif terkait berhasil dihapus.']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,12 +49,13 @@ public function store(Request $request)
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
// Log::info($id);
|
||||
$id = str($id);
|
||||
$vehicleRates = DB::table("tarif")->where("id_mobil", $id)->first();
|
||||
$vehicleRates = DB::table("tarif")->where("id_mobil", (string) $id)->first();
|
||||
|
||||
Log::info(json_encode($vehicleRates));
|
||||
return $vehicleRates;
|
||||
if (!$vehicleRates) {
|
||||
return response()->json(['status' => false, 'message' => 'Tarif kendaraan tidak ditemukan.'], 404);
|
||||
}
|
||||
|
||||
return response()->json($vehicleRates);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,14 +78,43 @@ public function edit($id)
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
Log::info($request->all());
|
||||
// $id = $request->id_mobil;
|
||||
|
||||
$dataQuery = MasterTarif::find($id);
|
||||
try {
|
||||
Log::info($request->all());
|
||||
if (!$dataQuery) {
|
||||
return response()->json(['status' => false, 'message' => 'Tarif kendaraan tidak ditemukan.'], 404);
|
||||
}
|
||||
|
||||
$dataQuery->fill($request->all());
|
||||
$validated = $request->validate([
|
||||
'waktu_gratis' => 'nullable|integer|min:0',
|
||||
'tarif_period' => 'nullable|numeric|min:0',
|
||||
'frek_interval' => 'nullable|integer|min:1',
|
||||
'interval' => 'nullable|integer|min:1',
|
||||
'tarif_interval' => 'nullable|numeric|min:0',
|
||||
'bayar_dimuka' => 'nullable|boolean',
|
||||
'asuransi_incl' => 'nullable|numeric|min:0',
|
||||
'frek_waktu2' => 'nullable|integer|min:1',
|
||||
'waktu2' => 'nullable|integer|min:1',
|
||||
'tarif2' => 'nullable|numeric|min:0',
|
||||
'tarif' => 'required|numeric|min:0',
|
||||
'waktu_tarif' => 'nullable|integer|min:1',
|
||||
'maksimum' => 'nullable|numeric|min:0',
|
||||
'maksimum_mode' => 'required|in:hour,day',
|
||||
'maksimum_hour' => 'nullable|integer|min:1',
|
||||
'maksimum_day_minute' => 'nullable|integer|min:0',
|
||||
'denda' => 'nullable|numeric|min:0',
|
||||
'denda_member' => 'nullable|integer|min:0',
|
||||
'denda_only_casual' => 'nullable|boolean',
|
||||
'denda_only' => 'nullable|boolean',
|
||||
]);
|
||||
|
||||
try {
|
||||
$data = collect($validated)->except(['maksimum_mode', 'maksimum_hour', 'maksimum_day_minute'])->all();
|
||||
$data['time_base'] = $validated['maksimum_mode'] === 'hour' ? 1 : 0;
|
||||
$data['time_base_maks'] = $validated['maksimum_mode'] === 'hour' ? $validated['maksimum_hour'] : null;
|
||||
$data['min_per_hari'] = $validated['maksimum_mode'] === 'day' ? $validated['maksimum_day_minute'] : null;
|
||||
$data['denda_only_casual'] = $request->boolean('denda_only_casual') ? 1 : 0;
|
||||
$data['denda_only'] = $request->boolean('denda_only') ? 1 : 0;
|
||||
|
||||
$dataQuery->fill($data);
|
||||
|
||||
if (!$dataQuery->isDirty()) {
|
||||
return response()->json([
|
||||
@@ -92,7 +122,6 @@ public function update(Request $request, $id)
|
||||
"message" => "Tidak ada perubahan data",
|
||||
]);
|
||||
}
|
||||
Log::info("Data yang di simpan" . json_encode($dataQuery->getDirty()));
|
||||
$dataQuery->save();
|
||||
|
||||
return response()->json([
|
||||
@@ -100,10 +129,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($request->all());
|
||||
|
||||
Log::error('Gagal memperbarui tarif kendaraan', ['id_mobil' => $id, 'error' => $th->getMessage()]);
|
||||
return response()->json([
|
||||
"status" => false,
|
||||
"message" => "Gagal menyimpan data " . $th->getMessage(),
|
||||
|
||||
@@ -11,18 +11,31 @@ class SetupController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$status = [
|
||||
'pgcrypto' => $this->checkPgcrypto(),
|
||||
'pegawai_columns' => $this->checkPegawaiColumns(),
|
||||
'users_view' => $this->checkUsersView(),
|
||||
'veri_time' => Schema::hasColumn('transaksi_parkir', 'veri_time'),
|
||||
];
|
||||
$status = $this->status();
|
||||
|
||||
return view('welcome', compact('status'));
|
||||
return view('welcome', ['isReady' => $this->isReady($status)]);
|
||||
}
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$status = $this->status();
|
||||
|
||||
if ($this->isReady($status)) {
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
return view('setup', compact('status'));
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
if ($this->isReady($this->status())) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Setup database sudah selesai dan tidak perlu dijalankan ulang.',
|
||||
], 403);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
@@ -66,6 +79,18 @@ public function run()
|
||||
});
|
||||
}
|
||||
|
||||
// 5. Laravel database sessions for authenticated web requests.
|
||||
if (!Schema::hasTable('sessions')) {
|
||||
Schema::create('sessions', function ($table) {
|
||||
$table->string('id')->primary();
|
||||
$table->unsignedBigInteger('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
});
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
// return redirect()->back()->with('success', 'Setup berhasil dijalankan ✅');
|
||||
@@ -84,6 +109,26 @@ public function run()
|
||||
}
|
||||
}
|
||||
|
||||
private function status(): array
|
||||
{
|
||||
return [
|
||||
'pgcrypto' => $this->checkPgcrypto(),
|
||||
'pegawai_columns' => $this->checkPegawaiColumns(),
|
||||
'users_view' => $this->checkUsersView(),
|
||||
'veri_time' => Schema::hasColumn('transaksi_parkir', 'veri_time'),
|
||||
'sessions' => Schema::hasTable('sessions'),
|
||||
];
|
||||
}
|
||||
|
||||
private function isReady(array $status): bool
|
||||
{
|
||||
return $status['pgcrypto']
|
||||
&& $status['users_view']
|
||||
&& $status['veri_time']
|
||||
&& $status['sessions']
|
||||
&& !in_array(false, $status['pegawai_columns'], true);
|
||||
}
|
||||
|
||||
/* =========================
|
||||
Helper
|
||||
========================= */
|
||||
|
||||
Reference in New Issue
Block a user