update vehicle trips report to include trip duration and distance

This commit is contained in:
wayanrivan
2026-07-07 12:46:36 +07:00
parent 67cff7d667
commit 39dbdf1795
2 changed files with 174 additions and 85 deletions

View File

@ -176,11 +176,14 @@ class ReportsController extends Controller
t.*,
tm.total_mileage, total_trip,
vt.name as type_name,
ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.start) AS trip_id
ROW_NUMBER() OVER (PARTITION BY t.id ORDER BY t.start) AS trip_id,
tgt.latitude,
tgt.longitude
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
LEFT JOIN t_gps_tracks tgt ON t.vhc_id = tgt.vhc_id
WHERE
t.start BETWEEN ? AND ?
and (? IS NULL or t.id = ?)

View File

@ -117,6 +117,8 @@
<th class="hidden">Date</th>
<th class="hidden">Hour Start</th>
<th class="hidden">Hour Finish</th>
<th class="hidden">Latitude</th>
<th class="hidden">Longitude</th>
<th class="">Start</th>
<th class="">Finish</th>
<th class="">Duration</th>
@ -291,6 +293,70 @@
});
},
};
// Data referensi site (lat/lng dalam desimal, bukan koma)
const SITE_LOCATIONS = [{
name: 'Bitterlaun',
district: 'Dili',
subdistrict: 'Cristo Rei',
village: 'Hera',
lat: -8.548328,
lng: 125.623808
},
{
name: 'Bebonuk',
district: 'Dili',
subdistrict: 'Dom Aleixo',
village: 'Comoro',
lat: -8.547527,
lng: 125.548280
},
{
name: 'Balide',
district: 'Dili',
subdistrict: 'Nain Feto',
village: 'Santa Cruz',
lat: -8.564396,
lng: 125.582151
},
];
// Radius toleransi "berdekatan" dalam meter — sesuaikan sesuai kebutuhan
const SITE_PROXIMITY_RADIUS_METERS = 150;
// Hitung jarak antara 2 koordinat (formula Haversine), hasil dalam meter
function getDistanceMeters(lat1, lon1, lat2, lon2) {
const R = 6371000; // radius bumi (meter)
const toRad = (deg) => deg * Math.PI / 180;
const dLat = toRad(lat2 - lat1);
const dLon = toRad(lon2 - lon1);
const a = Math.sin(dLat / 2) ** 2 +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLon / 2) ** 2;
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
// Cari site terdekat dari koordinat yang diberikan; null jika tidak ada yang cukup dekat
function findNearestSite(lat, lng) {
if (lat === undefined || lng === undefined || lat === null || lng === null || lat === '' || lng === '') {
return null;
}
let nearest = null;
let minDist = Infinity;
SITE_LOCATIONS.forEach(site => {
const dist = getDistanceMeters(parseFloat(lat), parseFloat(lng), site.lat, site.lng);
if (dist <= SITE_PROXIMITY_RADIUS_METERS && dist < minDist) {
minDist = dist;
nearest = site;
}
});
return nearest;
}
// Format label sesuai output yang diinginkan
function formatSiteLabel(site) {
return `Site ${site.name}, ${site.village}, ${site.subdistrict}, ${site.district}, Timor-Leste`;
}
const DTable = {
table: null,
@ -417,11 +483,31 @@
`;
}
},
// {
// data: 'finish',
// render: (data, type, row, meta) => {
// // saat export, hanya tampilkan lokasi tanpa tanggal/jam
// if (type === 'export') {
// return Helper.shortenText(decodeURIComponent(row.finishLoc ||
// 'address'), 255) || "-";
// }
// return `
// ${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}<br>
// ${Helper.shortenText(decodeURIComponent(row.finishLoc || 'address'), 255) || "-"}
// `;
// }
// },
{
data: 'finish',
render: (data, type, row, meta) => {
// saat export, hanya tampilkan lokasi tanpa tanggal/jam
// saat export, cek apakah koordinat finish berdekatan dengan site referensi
if (type === 'export') {
const nearestSite = findNearestSite(row.finishLat, row
.finishLng); // sesuaikan nama field lat/lng
if (nearestSite) {
return formatSiteLabel(nearestSite);
}
// default: tetap pakai alamat dari database
return Helper.shortenText(decodeURIComponent(row.finishLoc ||
'address'), 255) || "-";
}