This commit is contained in:
wayanrivan
2026-07-20 09:49:29 +07:00
parent 32229a1b52
commit bb18878336
2 changed files with 145 additions and 113 deletions

View File

@ -63,12 +63,24 @@ class ReportsController extends Controller
// $to_date = $req->input('to_date'); // $to_date = $req->input('to_date');
$from_date = $req->input('from_date') - Helper::TIMEFIX; $from_date = $req->input('from_date') - Helper::TIMEFIX;
$to_date = $req->input('to_date') - Helper::TIMEFIX; $to_date = $req->input('to_date') - Helper::TIMEFIX;
$vid = $req->input('vid');
// vid sekarang bisa berupa multiple value (dari select2 multiple di FE)
// bisa datang sebagai array (vid[]=1&vid[]=2) atau string comma-separated ("1,2,3")
$vidInput = $req->input('vid');
$vt = $req->input('vt'); $vt = $req->input('vt');
$poolcode = $req->input('poolcode'); $poolcode = $req->input('poolcode');
// $from_date = 1756054800; // $from_date = 1756054800;
// $to_date = 1756745940; // $to_date = 1756745940;
// Normalisasi $vid jadi array of int, buang value kosong (mis. opsi "-- All --")
$vidArr = [];
if (is_array($vidInput)) {
$vidArr = array_filter($vidInput, fn($v) => $v !== null && $v !== '');
} elseif (!empty($vidInput)) {
$vidArr = array_filter(explode(',', $vidInput), fn($v) => $v !== '');
}
$vidArr = array_values($vidArr);
// get month year // get month year
$date = Carbon::createFromTimestamp($from_date); $date = Carbon::createFromTimestamp($from_date);
$yymm = $date->format('ym'); $yymm = $date->format('ym');
@ -166,52 +178,70 @@ class ReportsController extends Controller
// and if(? , vt.id = ? , 1=1) // and if(? , vt.id = ? , 1=1)
// and if(? , t.pool_code = ? , 1=1) // and if(? , t.pool_code = ? , 1=1)
// ", [$from_date, $to_date, $from_date, $to_date, $vid, $vid, $vt, $vt, $poolcode, $poolcode]); // ", [$from_date, $to_date, $from_date, $to_date, $vid, $vid, $vt, $vt, $poolcode, $poolcode]);
// Bangun klausa IN untuk vid secara dinamis (jumlah placeholder = jumlah item terpilih)
// kalau kosong -> tidak difilter (1=1)
if (count($vidArr) > 0) {
$vidPlaceholders = implode(',', array_fill(0, count($vidArr), '?'));
$vidCondition = "t.id IN ($vidPlaceholders)";
} else {
$vidCondition = "1=1";
}
$sql = $sql =
"WITH TotalMileage AS ( "WITH TotalMileage AS (
SELECT
id,
SUM(mileage) AS total_mileage,
COUNT(*) AS total_trip
FROM trips
WHERE start BETWEEN ? AND ?
GROUP BY id
)
SELECT SELECT
t.*, id,
tm.total_mileage, SUM(mileage) AS total_mileage,
tm.total_trip, COUNT(*) AS total_trip
vt.name AS type_name, FROM trips
ROW_NUMBER() OVER ( WHERE start BETWEEN ? AND ?
PARTITION BY t.id GROUP BY id
ORDER BY t.start )
) AS trip_id SELECT
FROM trips t t.*,
JOIN TotalMileage tm ON t.id = tm.id tm.total_mileage,
LEFT JOIN t_vehicles tvt ON tvt.id = t.vhc_id tm.total_trip,
LEFT JOIN t_vehicles_cats vt ON vt.id = tvt.cat_id vt.name AS type_name,
WHERE ROW_NUMBER() OVER (
t.start BETWEEN ? AND ? PARTITION BY t.id
AND (? IS NULL OR t.id = ?) ORDER BY t.start
AND (? IS NULL OR vt.id = ?) ) AS trip_id
AND (? IS NULL OR t.pool_code = ?); FROM trips t
"; JOIN TotalMileage tm ON t.id = tm.id
LEFT JOIN t_vehicles tvt ON tvt.id = t.vhc_id
LEFT JOIN t_vehicles_cats vt ON vt.id = tvt.cat_id
WHERE
t.start BETWEEN ? AND ?
AND {$vidCondition}
AND (? IS NULL OR vt.id = ?)
AND (? IS NULL OR t.pool_code = ?);
";
$vid = $vid ?: null;
$vt = $vt ?: null; $vt = $vt ?: null;
$poolcode = $poolcode ?: null; $poolcode = $poolcode ?: null;
$list = DB::select($sql, [ $bindings = [
$from_date, $from_date,
$to_date, $to_date,
$from_date, $from_date,
$to_date, $to_date,
$vid, ];
$vid,
// masukkan binding untuk IN(...) hanya kalau ada isinya
if (count($vidArr) > 0) {
$bindings = array_merge($bindings, $vidArr);
}
$bindings = array_merge($bindings, [
$vt, $vt,
$vt, $vt,
$poolcode, $poolcode,
$poolcode, $poolcode,
]); ]);
$list = DB::select($sql, $bindings);
// // RETURN 1 - LIST // // RETURN 1 - LIST
// if($req->type != 'report'){ // if($req->type != 'report'){
$apiResp = Responses::success("success list vehicles report"); $apiResp = Responses::success("success list vehicles report");

View File

@ -25,8 +25,8 @@
@if ($user_role == \App\Models\Users::ROLE_VENDOR || $user_role == \App\Models\Users::ROLE_ADMIN) @if ($user_role == \App\Models\Users::ROLE_VENDOR || $user_role == \App\Models\Users::ROLE_ADMIN)
@can('vehicle.create') @can('vehicle.create')
<!-- <div class="col text-end"> <!-- <div class="col text-end">
<button id="btnMdlNewVhc" class="btn btn-sm btn-danger">Add New Vehicle</button> <button id="btnMdlNewVhc" class="btn btn-sm btn-danger">Add New Vehicle</button>
</div> --> </div> -->
@endcan @endcan
{{-- <div class="col-auto text-end ps-0"> {{-- <div class="col-auto text-end ps-0">
@ -59,7 +59,8 @@
<div class="col-6 col-md-3 col-lg-2"> <div class="col-6 col-md-3 col-lg-2">
<div class="form-group"> <div class="form-group">
<label class="form-label text-muted mb-1">License Plate</label> <label class="form-label text-muted mb-1">License Plate</label>
<select name="license_plate" class="form-control" id="filterNopol"> <select name="license_plate" class="form-control" id="filterNopol" style="width:100%;"
multiple="multiple">
<option value="">-- All --</option> <option value="">-- All --</option>
@foreach ($listNopol as $nopol) @foreach ($listNopol as $nopol)
<option value="{{ $nopol->id }}">{{ $nopol->nopol1 }}</option> <option value="{{ $nopol->id }}">{{ $nopol->nopol1 }}</option>
@ -129,73 +130,73 @@
</tr> </tr>
</thead> </thead>
<!-- <tbody> <!-- <tbody>
<tr> <tr>
<td>24-679</td> <td>24-679</td>
<td>24-679</td> <td>24-679</td>
<td>26</td> <td>26</td>
<td>442.3</td> <td>442.3</td>
</tr> </tr>
<tr> <tr>
<td>24-682</td> <td>24-682</td>
<td>24-682</td> <td>24-682</td>
<td>28</td> <td>28</td>
<td>312.7</td> <td>312.7</td>
</tr> </tr>
<tr> <tr>
<td>24-877</td> <td>24-877</td>
<td>24-877</td> <td>24-877</td>
<td>15</td> <td>15</td>
<td>276.4</td> <td>276.4</td>
</tr> </tr>
<tr> <tr>
<td>A.16-347</td> <td>A.16-347</td>
<td>A.16-347</td> <td>A.16-347</td>
<td>37</td> <td>37</td>
<td>543.2</td> <td>543.2</td>
</tr> </tr>
<tr> <tr>
<td>AL2025-B21</td> <td>AL2025-B21</td>
<td>AL2025-B21</td> <td>AL2025-B21</td>
<td>18</td> <td>18</td>
<td>295.4</td> <td>295.4</td>
</tr> </tr>
<tr> <tr>
<td>B.16-542</td> <td>B.16-542</td>
<td>B.16-542</td> <td>B.16-542</td>
<td>32</td> <td>32</td>
<td>478.2</td> <td>478.2</td>
</tr> </tr>
<tr> <tr>
<td>B.24-264</td> <td>B.24-264</td>
<td>B.24-264</td> <td>B.24-264</td>
<td>24</td> <td>24</td>
<td>188.4</td> <td>188.4</td>
</tr> </tr>
<tr> <tr>
<td>B.24-274</td> <td>B.24-274</td>
<td>B.24-274</td> <td>B.24-274</td>
<td>33</td> <td>33</td>
<td>440.1</td> <td>440.1</td>
</tr> </tr>
<tr> <tr>
<td>Ford Ranger</td> <td>Ford Ranger</td>
<td>26-199</td> <td>26-199</td>
<td>30</td> <td>30</td>
<td>631.4</td> <td>631.4</td>
</tr> </tr>
<tr> <tr>
<td>Nissan AD</td> <td>Nissan AD</td>
<td>B.10-517</td> <td>B.10-517</td>
<td>27</td> <td>27</td>
<td>375.9</td> <td>375.9</td>
</tr> </tr>
<tr> <tr>
<td>Triton</td> <td>Triton</td>
<td>A.29-127</td> <td>A.29-127</td>
<td>26</td> <td>26</td>
<td>508.2</td> <td>508.2</td>
</tr> </tr>
</tbody> --> </tbody> -->
</table> </table>
</div> </div>
</div> </div>
@ -207,17 +208,17 @@
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDetailTrip" <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlDetailTrip"
aria-labelledby="mdlDetailTripLabel" aria-hidden="true"> aria-labelledby="mdlDetailTripLabel" aria-hidden="true">
<!-- <div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl"> <!-- <div class="modal-dialog modal-dialog modal-dialog-centered modal-dialog-scrollable modal-xl">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="mdlDetailTripLabel">-----</h5> <h5 class="modal-title" id="mdlDetailTripLabel">-----</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
</div>
</div> </div>
<div class="modal-body"> </div> -->
</div>
<div class="modal-footer">
</div>
</div>
</div> -->
</div> </div>
@endsection @endsection
@ -289,6 +290,7 @@
}) })
}); });
$('#filterNopol').select2({});
}, },
}; };
// Data referensi site (lat/lng dalam desimal, bukan koma) // Data referensi site (lat/lng dalam desimal, bukan koma)
@ -514,7 +516,7 @@
const nearestSite = findNearestSite(startLat, startLng); const nearestSite = findNearestSite(startLat, startLng);
if (nearestSite) { if (nearestSite) {
return formatSiteLabel(nearestSite); return `${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}<br>`+formatSiteLabel(nearestSite);
} }
return ` return `
${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}<br> ${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}<br>
@ -548,7 +550,7 @@
const nearestSite = findNearestSite(finishLat, finishLng); const nearestSite = findNearestSite(finishLat, finishLng);
if (nearestSite) { if (nearestSite) {
return formatSiteLabel(nearestSite); return `${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}<br>`+formatSiteLabel(nearestSite);
} }
// Tampilan di tabel // Tampilan di tabel