update
This commit is contained in:
@ -31,8 +31,8 @@
|
||||
@if ($user_role == \App\Models\Users::ROLE_VENDOR || $user_role == \App\Models\Users::ROLE_ADMIN)
|
||||
@can('vehicle.create')
|
||||
<!-- <div class="col text-end">
|
||||
<button id="btnMdlNewVhc" class="btn btn-sm btn-danger">Add New Vehicle</button>
|
||||
</div> -->
|
||||
<button id="btnMdlNewVhc" class="btn btn-sm btn-danger">Add New Vehicle</button>
|
||||
</div> -->
|
||||
@endcan
|
||||
|
||||
{{-- <div class="col-auto text-end ps-0">
|
||||
@ -314,6 +314,20 @@
|
||||
// Timestamp 'start' TIDAK diubah karena itu waktu kejadian sebenarnya —
|
||||
// yang disamakan hanya titik lokasi & odometer supaya laporan terlihat
|
||||
// kontinu (finish trip N == start trip N+1).
|
||||
//
|
||||
// PENTING: perbandingan koordinat dilakukan secara NUMERIK (parseFloat +
|
||||
// hitung jarak meter via getDistanceMeters), BUKAN string mentah.
|
||||
// Ini supaya kasus seperti berikut tetap terdeteksi & diperbaiki:
|
||||
// - km/odometer sudah nyambung (finish trip N == start trip N+1)
|
||||
// TAPI titik GPS-nya beda beberapa meter (drift GPS), sehingga
|
||||
// salah satu titik "masuk" radius site tertentu (mis. "Bank BNU")
|
||||
// dan yang lain tidak -> teks lokasi jadi kelihatan "loncat"
|
||||
// walau kendaraan sebenarnya di tempat yang sama.
|
||||
// Toleransi 0 meter berarti: kalau titiknya tidak PERSIS sama,
|
||||
// selalu disamakan dengan finish sebelumnya. Ini paling aman untuk
|
||||
// laporan (finish trip N akan selalu == start trip N+1).
|
||||
const TRIP_CONTINUITY_TOLERANCE_METERS = 0; // >>> ADDED
|
||||
|
||||
function normalizeTripContinuity(rows) { // >>> ADDED
|
||||
if (!Array.isArray(rows) || rows.length === 0) return rows;
|
||||
|
||||
@ -333,14 +347,54 @@
|
||||
const prev = groupRows[i - 1];
|
||||
const curr = groupRows[i];
|
||||
|
||||
const locMismatch = (prev.finish_lat_long || '').trim() !== (curr.start_lat_long || '')
|
||||
.trim();
|
||||
// 1) Cek mismatch km/odometer
|
||||
const kmMismatch = Number(prev.finishMileage) !== Number(curr.startMileage);
|
||||
|
||||
if (locMismatch || kmMismatch) {
|
||||
// 2) Cek mismatch koordinat GPS -- HANYA kalau datanya tersedia,
|
||||
// karena banyak data (seperti contoh Anda) punya
|
||||
// start_lat_long/finish_lat_long = null untuk semua baris.
|
||||
const prevCoord = parseLatLong(prev.finish_lat_long);
|
||||
const currCoord = parseLatLong(curr.start_lat_long);
|
||||
let coordMismatch = false;
|
||||
if (prevCoord.lat !== null && currCoord.lat !== null) {
|
||||
const distMeters = getDistanceMeters(
|
||||
prevCoord.lat, prevCoord.lng,
|
||||
currCoord.lat, currCoord.lng
|
||||
);
|
||||
coordMismatch = distMeters > TRIP_CONTINUITY_TOLERANCE_METERS;
|
||||
}
|
||||
|
||||
// 3) Cek mismatch TEKS lokasi (startLoc vs finishLoc). Ini penting
|
||||
// karena saat lat_long null, satu-satunya sumber lokasi yang
|
||||
// dipakai untuk render adalah field teks ini (lihat kolom
|
||||
// Start/Finish -> prioritas 2: row.startLoc / row.finishLoc).
|
||||
// Tanpa cek ini, kasus seperti "Estrada Suai - Maliana, Cendana"
|
||||
// vs "Bank BNU, Estrada Suai - Maliana, Cendana" tidak akan
|
||||
// terdeteksi sebagai mismatch walau km-nya sudah nyambung.
|
||||
const prevFinishText = (prev.finishLoc || '').trim();
|
||||
const currStartText = (curr.startLoc || '').trim();
|
||||
const textMismatch = prevFinishText !== currStartText;
|
||||
|
||||
if (kmMismatch || coordMismatch || textMismatch) {
|
||||
curr.start_lat_long = prev.finish_lat_long;
|
||||
curr.startLoc = prev.finishLoc;
|
||||
curr.startMileage = prev.finishMileage;
|
||||
|
||||
// Hitung ulang Distance (kolom 'mileage') dari selisih odometer
|
||||
// yang baru (finishMileage - startMileage yang sudah disinkronkan),
|
||||
// supaya kolom Distance tetap konsisten dengan kolom Start(km)/Finish(km)
|
||||
// yang tampil di tabel. Sebelumnya 'mileage' berasal dari GPS track
|
||||
// mentah, yang bisa beda dengan selisih odometer setelah normalisasi ini.
|
||||
//
|
||||
// - Kalau hasilnya minus (finishMileage < startMileage, misal odometer
|
||||
// sempat reset/kebalik), jadikan positif (absolute value).
|
||||
// - Lalu bulatkan ke bilangan bulat terdekat: desimal >= 0.5 dibulatkan
|
||||
// ke atas, desimal < 0.5 dibulatkan ke bawah (standard round-half-up;
|
||||
// Math.round sudah berlaku demikian untuk angka positif).
|
||||
const rawDiff = Number(curr.finishMileage) - Number(curr.startMileage);
|
||||
if (!isNaN(rawDiff)) {
|
||||
curr.mileage = Math.round(Math.abs(rawDiff));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -600,7 +654,8 @@
|
||||
locationLabel = formatSiteLabel(nearestSite);
|
||||
} else if (row.startLoc) {
|
||||
// Prioritas 2: startLoc sudah ada dari API
|
||||
locationLabel = Helper.shortenText(decodeURIComponent(row.startLoc), 255);
|
||||
locationLabel = Helper.shortenText(decodeURIComponent(row
|
||||
.startLoc), 255);
|
||||
} else if (type === 'export') {
|
||||
// Export bersifat sinkron, tidak bisa menunggu hasil geocode background
|
||||
locationLabel = '-';
|
||||
@ -630,7 +685,8 @@
|
||||
if (nearestSite) {
|
||||
locationLabel = formatSiteLabel(nearestSite);
|
||||
} else if (row.finishLoc) {
|
||||
locationLabel = Helper.shortenText(decodeURIComponent(row.finishLoc), 255);
|
||||
locationLabel = Helper.shortenText(decodeURIComponent(row
|
||||
.finishLoc), 255);
|
||||
} else if (type === 'export') {
|
||||
locationLabel = '-';
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user