diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 499ef23..062c235 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -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 = ?) diff --git a/resources/views/menu_v1/reports/vehicle_trips.blade.php b/resources/views/menu_v1/reports/vehicle_trips.blade.php index 37f9d52..75e2aca 100644 --- a/resources/views/menu_v1/reports/vehicle_trips.blade.php +++ b/resources/views/menu_v1/reports/vehicle_trips.blade.php @@ -25,8 +25,8 @@ @if ($user_role == \App\Models\Users::ROLE_VENDOR || $user_role == \App\Models\Users::ROLE_ADMIN) @can('vehicle.create') + + --> @endcan {{--
@@ -117,6 +117,8 @@ Date Hour Start Hour Finish + Latitude + Longitude Start Finish Duration @@ -129,73 +131,73 @@ + + 24-679 + 24-679 + 26 + 442.3 + + + 24-682 + 24-682 + 28 + 312.7 + + + 24-877 + 24-877 + 15 + 276.4 + + + A.16-347 + A.16-347 + 37 + 543.2 + + + AL2025-B21 + AL2025-B21 + 18 + 295.4 + + + B.16-542 + B.16-542 + 32 + 478.2 + + + B.24-264 + B.24-264 + 24 + 188.4 + + + B.24-274 + B.24-274 + 33 + 440.1 + + + Ford Ranger + 26-199 + 30 + 631.4 + + + Nissan AD + B.10-517 + 27 + 375.9 + + + Triton + A.29-127 + 26 + 508.2 + + -->
@@ -207,17 +209,17 @@ --> @endsection @@ -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,18 +483,38 @@ `; } }, + // { + // 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')}
+ // ${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) || "-"; } return ` - ${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}
- ${Helper.shortenText(decodeURIComponent(row.finishLoc || 'address'), 255) || "-"} - `; + ${moment.unix(data + AppState.TIMEFIX).format('DD MMM YYYY HH:mm:ss')}
+ ${Helper.shortenText(decodeURIComponent(row.finishLoc || 'address'), 255) || "-"} + `; } }, {