diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 0a6e52d..2adff9f 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -292,134 +292,30 @@ class ReportsController extends Controller // } // } -public function api_report_vehicle_trips_list(Request $req) -{ - // $TIMEFIX = Helper::TIMEFIX; - // Validate input - // date in unix datetime format - // dd($req->type); - $rules = [ - // 'from_date' => 'required|date', - // 'to_date' => 'required|date|after_or_equal:from_date', - 'type' => 'nullable|in:report,list', // enum "report", "list". nullable default "list" - ]; + public function api_report_vehicle_trips_list(Request $req) + { + $rules = [ + 'type' => 'nullable|in:report,list', // enum "report", "list". nullable default "list" + ]; - $isValidInput = Validator::make($req->all(), $rules); - if (!$isValidInput->passes()) { - $apiResp = Responses::bad_input($isValidInput->messages()->first()); - return new Response($apiResp, $apiResp["meta"]["code"]); - } + $isValidInput = Validator::make($req->all(), $rules); + if (!$isValidInput->passes()) { + $apiResp = Responses::bad_input($isValidInput->messages()->first()); + return new Response($apiResp, $apiResp["meta"]["code"]); + } - // $from_date = $req->input('from_date'); - // $to_date = $req->input('to_date'); - $from_date = $req->input('from_date') - Helper::TIMEFIX; - $to_date = $req->input('to_date') - Helper::TIMEFIX; - $vid = $req->input('vid'); - $vt = $req->input('vt'); - $poolcode = $req->input('poolcode'); - // $from_date = 1756054800; - // $to_date = 1756745940; + $from_date = $req->input('from_date') - Helper::TIMEFIX; + $to_date = $req->input('to_date') - Helper::TIMEFIX; + $vid = $req->input('vid'); + $vt = $req->input('vt'); + $poolcode = $req->input('poolcode'); - // get month year - $date = Carbon::createFromTimestamp($from_date); - $yymm = $date->format('ym'); + $date = Carbon::createFromTimestamp($from_date); + $yymm = $date->format('ym'); - try { - // $list = DB::select("WITH - // gaps AS ( - // SELECT - // -- previous gap since previous row > 1 hour (3600s) - // CASE - // WHEN (crt_d - LAG(crt_d, 1, NULL) OVER (PARTITION BY vhc_id ORDER BY crt_d)) > 3600 - // THEN 1 ELSE 0 - // END AS isStop, - // t.* - // FROM tracks_2509 t - // WHERE - // t.latitude IS NOT NULL - // AND t.longitude IS NOT NULL - // AND t.action = 'location' - // AND t.crt_d BETWEEN ? AND ? - // ) - // , trips AS ( - // SELECT - // -- mark the start of a trip when ignition=4 and previous ignition <> 4 - // CASE - // WHEN ignition = 4 - // AND LAG(ignition, 1, 0) OVER (PARTITION BY vhc_id ORDER BY crt_d) <> 4 - // or LAG(isStop, 1, 0) over (PARTITION BY vhc_id ORDER BY crt_d) = 1 - // THEN 1 ELSE 0 - // END AS trip_start, - // g.* - // FROM gaps g - // ) - // , numbered AS ( - // SELECT - // *, - // -- assign a trip_id by cumulative sum of trip_start - // SUM(trip_start) OVER (PARTITION BY vhc_id ORDER BY crt_d) AS trip_id - // FROM trips - // where - // ignition = 4 - // and isStop = 0 - // ), - // agg AS ( - // SELECT - // COUNT(*) AS row_count, - // v.name, - // v.nopol1, - // vhc_id, - // -- trip_id, - // ROW_NUMBER() OVER (PARTITION BY v.id ORDER BY MIN(a.crt_d)) AS trip_id, - // SUM(pre_milleage) AS mileage, - // MIN(a.crt_d) AS start, - // MAX(a.crt_d) AS finish, - // MIN(a.vhc_milleage) AS startMileage, - // MAX(a.vhc_milleage) AS finishMileage, - // (SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MIN(a.id) LIMIT 1) AS startLoc, - // (SELECT fulladdress FROM t_gps_tracks_address WHERE master_id = MAX(a.id) LIMIT 1) AS finishLoc - // FROM t_vehicles v - // LEFT JOIN numbered a ON a.vhc_id = v.id - // WHERE - // v.dlt is null and trip_id != 0 - // and if(? , v.id = ? , 1=1) - // GROUP BY v.id, a.trip_id - // HAVING COUNT(*) > 1 - // ) - // SELECT - // *, - // SUM(mileage) OVER (PARTITION BY agg.id) AS total_mileage, - // COUNT(trip_id) OVER (PARTITION BY agg.id) AS total_trip, - // tvd.pool_code, tvd.dc_code - // FROM agg agg - // join t_vehicles_detail tvd on tvd.vid = agg.vhc_id - // ORDER BY agg.id, trip_id - // ", [$from_date, $to_date, $vid, $vid]); - - // $list = DB::select("WITH TotalMileage AS ( - // SELECT id, SUM(mileage) AS total_mileage, count(*) total_trip - // FROM trips - // WHERE start BETWEEN ? AND ? - // GROUP BY id - // ) - // SELECT - // 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 - // 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 if(? , t.id = ? , 1=1) - // and if(? , vt.id = ? , 1=1) - // and if(? , t.pool_code = ? , 1=1) - // ", [$from_date, $to_date, $from_date, $to_date, $vid, $vid, $vt, $vt, $poolcode, $poolcode]); - - $sql = - "WITH TotalMileage AS ( + try { + $sql = + "WITH TotalMileage AS ( SELECT id, SUM(mileage) AS total_mileage, @@ -448,40 +344,44 @@ public function api_report_vehicle_trips_list(Request $req) AND (? IS NULL OR t.pool_code = ?); "; - $vid = $vid ?: null; - $vt = $vt ?: null; - $poolcode = $poolcode ?: null; + $vid = $vid ?: null; + $vt = $vt ?: null; + $poolcode = $poolcode ?: null; - $list = DB::select($sql, [ - $from_date, - $to_date, - $from_date, - $to_date, - $vid, - $vid, - $vt, - $vt, - $poolcode, - $poolcode, - ]); + $list = DB::select($sql, [ + $from_date, + $to_date, + $from_date, + $to_date, + $vid, + $vid, + $vt, + $vt, + $poolcode, + $poolcode, + ]); - /** - * ========================================================== - * GET LAST GPS POSITION FOR EACH VEHICLE - * ========================================================== - */ - $vehicleIds = collect($list) - ->pluck('vhc_id') - ->filter() - ->unique() - ->values() - ->toArray(); + /** + * ========================================================== + * GET LAST GPS POSITION (YANG SUDAH PUNYA FULLADDRESS) + * ========================================================== + */ + $vehicleIds = collect($list) + ->pluck('vhc_id') + ->filter() + ->unique() + ->values() + ->toArray(); - if (!empty($vehicleIds)) { + if (!empty($vehicleIds)) { - $placeholders = implode(',', array_fill(0, count($vehicleIds), '?')); + $placeholders = implode(',', array_fill(0, count($vehicleIds), '?')); - $gpsSql = " + // NOTE: subquery "latest" sekarang INNER JOIN ke t_gps_tracks_address + // supaya titik yang dipilih adalah titik terbaru yang ADDRESS-nya + // sudah selesai di-generate, bukan titik paling akhir mutlak yang + // mungkin belum sempat di-reverse-geocode. + $gpsSql = " SELECT gt.vhc_id, gt.latitude, @@ -490,126 +390,120 @@ public function api_report_vehicle_trips_list(Request $req) gt.crt_d, tgta.fulladdress FROM t_gps_tracks gt - LEFT JOIN t_gps_tracks_address tgta + INNER JOIN t_gps_tracks_address tgta ON tgta.master_id = gt.id INNER JOIN ( SELECT - vhc_id, - MAX(crt_d) AS last_crt_d - FROM t_gps_tracks + gt2.vhc_id, + MAX(gt2.crt_d) AS last_crt_d + FROM t_gps_tracks gt2 + INNER JOIN t_gps_tracks_address tgta2 + ON tgta2.master_id = gt2.id WHERE - action = 'location' - AND latitude IS NOT NULL - AND longitude IS NOT NULL - AND crt_d BETWEEN ? AND ? - AND vhc_id IN ($placeholders) - GROUP BY vhc_id + gt2.action = 'location' + AND gt2.latitude IS NOT NULL + AND gt2.longitude IS NOT NULL + AND gt2.crt_d BETWEEN ? AND ? + AND gt2.vhc_id IN ($placeholders) + GROUP BY gt2.vhc_id ) latest ON latest.vhc_id = gt.vhc_id AND latest.last_crt_d = gt.crt_d "; - $gpsParams = array_merge( - [$from_date, $to_date], - $vehicleIds - ); + $gpsParams = array_merge( + [$from_date, $to_date], + $vehicleIds + ); - $gpsList = DB::select($gpsSql, $gpsParams); + $gpsList = DB::select($gpsSql, $gpsParams); - $gpsByVehicle = collect($gpsList)->keyBy('vhc_id'); + $gpsByVehicle = collect($gpsList)->keyBy('vhc_id'); - foreach ($list as &$item) { + foreach ($list as &$item) { - $gps = $gpsByVehicle->get($item->vhc_id); + $gps = $gpsByVehicle->get($item->vhc_id); - $item->latitude = $gps->latitude ?? null; - $item->longitude = $gps->longitude ?? null; - $item->speed = $gps->speed ?? null; - $item->fulladdress = $gps->fulladdress ?? null; - $item->gps_time = $gps->crt_d ?? null; + $item->latitude = $gps->latitude ?? null; + $item->longitude = $gps->longitude ?? null; + $item->speed = $gps->speed ?? null; + $item->fulladdress = $gps->fulladdress ?? null; + $item->gps_time = $gps->crt_d ?? null; + } + + unset($item); } - unset($item); + $apiResp = Responses::success("success list vehicles report"); + $apiResp["data"] = $list; + return new Response($apiResp, $apiResp["meta"]["code"]); + + } catch (\Exception $e) { + $apiResp = Responses::error($e->getMessage()); + return new Response($apiResp, $apiResp["meta"]["code"]); } - - // // RETURN 1 - LIST - // if($req->type != 'report'){ - $apiResp = Responses::success("success list vehicles report"); - $apiResp["data"] = $list; - return new Response($apiResp, $apiResp["meta"]["code"]); - // } - - // // RETURN 2 - REPORT - // if($req->type == 'report'){ - // ... - // } - } catch (\Exception $e) { - $apiResp = Responses::error($e->getMessage()); - return new Response($apiResp, $apiResp["meta"]["code"]); - // return Responses::json(Responses::SERVER_ERROR, 'An error occurred while generating the report.', (object)[]); } -} - public function view_report_trip_detail(Request $req) - { - $vid = $req->vid; - $tgl0 = $req->tgl0; - $tgl1 = $req->tgl1; - $nopol1 = $req->nopol1; + // public function view_report_trip_detail(Request $req) +// { +// $vid = $req->vid; +// $tgl0 = $req->tgl0; +// $tgl1 = $req->tgl1; +// $nopol1 = $req->nopol1; - $d = [$vid, $tgl0, $tgl1]; - $list = DB::select("SELECT - t.crt_d , t.latitude, t.longitude, t.speed, - tgta.fulladdress, - t.pre_milleage, t.vhc_milleage, fuel_count - FROM - t_gps_tracks t - left join t_gps_tracks_address tgta on tgta.master_id = t.id - WHERE - t.vhc_id = ? - and t.latitude IS NOT NULL - AND t.longitude IS NOT NULL - AND t.action = 'location' - AND t.crt_d BETWEEN ? AND ? - ORDER BY t.crt_d asc - ", $d); + // $d = [$vid, $tgl0, $tgl1]; +// $list = DB::select("SELECT +// t.crt_d , t.latitude, t.longitude, t.speed, +// tgta.fulladdress, +// t.pre_milleage, t.vhc_milleage, fuel_count +// FROM +// t_gps_tracks t +// left join t_gps_tracks_address tgta on tgta.master_id = t.id +// WHERE +// t.vhc_id = ? +// and t.latitude IS NOT NULL +// AND t.longitude IS NOT NULL +// AND t.action = 'location' +// AND t.crt_d BETWEEN ? AND ? +// ORDER BY t.crt_d asc +// ", $d); - $start = [ - 'time' => $list[0]->crt_d, - 'fulladdress' => urldecode($list[0]->fulladdress), - 'mileage' => $list[0]->vhc_milleage, - ]; - $finish = [ - 'time' => $list[count($list) - 1]->crt_d, - 'fulladdress' => urldecode($list[count($list) - 1]->fulladdress), - 'mileage' => $list[count($list) - 1]->vhc_milleage, - ]; + // $start = [ +// 'time' => $list[0]->crt_d, +// 'fulladdress' => urldecode($list[0]->fulladdress), +// 'mileage' => $list[0]->vhc_milleage, +// ]; +// $finish = [ +// 'time' => $list[count($list) - 1]->crt_d, +// 'fulladdress' => urldecode($list[count($list) - 1]->fulladdress), +// 'mileage' => $list[count($list) - 1]->vhc_milleage, +// ]; - $t0 = Carbon::createFromTimestamp($list[0]->crt_d); - $t1 = Carbon::createFromTimestamp($list[count($list) - 1]->crt_d); - $diff = $t1->diff($t0); - $hours = $diff->h + ($diff->days * 24); // include days converted to hours - $minutes = $diff->i; - $duration = "{$hours} hour" . ($hours > 1 ? 's' : '') . " {$minutes} minute" . ($minutes > 1 ? 's' : ''); + // $t0 = Carbon::createFromTimestamp($list[0]->crt_d); +// $t1 = Carbon::createFromTimestamp($list[count($list) - 1]->crt_d); +// $diff = $t1->diff($t0); +// $hours = $diff->h + ($diff->days * 24); // include days converted to hours +// $minutes = $diff->i; +// $duration = "{$hours} hour" . ($hours > 1 ? 's' : '') . " {$minutes} minute" . ($minutes > 1 ? 's' : ''); - $distance = $list[count($list) - 1]->vhc_milleage - $list[0]->vhc_milleage; - $fuel_consumed = $list[count($list) - 1]->fuel_count - $list[0]->fuel_count; + // $distance = $list[count($list) - 1]->vhc_milleage - $list[0]->vhc_milleage; +// $fuel_consumed = $list[count($list) - 1]->fuel_count - $list[0]->fuel_count; - $data = [ - 'nopol1' => $nopol1, - 'vid' => $vid, - 'tgl0' => $tgl0, - 'tgl1' => $tgl1, - 'list' => $list, - 'start' => $start, - 'finish' => $finish, - 'duration' => $duration, - 'distance' => $distance, - 'fuel_consumed' => $fuel_consumed, - ]; - // dd($list); - return view('menu_v1.reports._trip_detail', $data); - } + // $data = [ +// 'nopol1' => $nopol1, +// 'vid' => $vid, +// 'tgl0' => $tgl0, +// 'tgl1' => $tgl1, +// 'list' => $list, +// 'start' => $start, +// 'finish' => $finish, +// 'duration' => $duration, +// 'distance' => $distance, +// 'fuel_consumed' => $fuel_consumed, +// ]; +// // dd($list); +// return view('menu_v1.reports._trip_detail', $data); +// } public function view_report_abnormalities(Request $req) { diff --git a/resources/views/menu_v1/reports/vehicle_trips.blade.php b/resources/views/menu_v1/reports/vehicle_trips.blade.php index 2717189..5f49885 100644 --- a/resources/views/menu_v1/reports/vehicle_trips.blade.php +++ b/resources/views/menu_v1/reports/vehicle_trips.blade.php @@ -319,7 +319,7 @@ ]; // Radius toleransi "berdekatan" dalam meter — sesuaikan sesuai kebutuhan - const SITE_PROXIMITY_RADIUS_METERS = 150; + const SITE_PROXIMITY_RADIUS_METERS = 500; // Hitung jarak antara 2 koordinat (formula Haversine), hasil dalam meter function getDistanceMeters(lat1, lon1, lat2, lon2) { @@ -481,23 +481,26 @@ `; } }, - // { - // 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 ` + // { + // 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) => { + console.log(row.fulladdress); + console.log(row.latitude); + console.log(row.longitude); // Saat export Excel if (type === 'export') {