From 79596192d3ec6ca41c7677eb818e89a123496724 Mon Sep 17 00:00:00 2001 From: meusinfirmary Date: Thu, 24 Jul 2025 03:10:14 +0700 Subject: [PATCH] update --- app/Models/Tracks.php | 295 ++------- app/Models/Tracks_copy_last.php | 1010 +++++++++++++++++++++++++++++++ 2 files changed, 1075 insertions(+), 230 deletions(-) create mode 100755 app/Models/Tracks_copy_last.php diff --git a/app/Models/Tracks.php b/app/Models/Tracks.php index ce6d6c2..f793377 100755 --- a/app/Models/Tracks.php +++ b/app/Models/Tracks.php @@ -347,14 +347,17 @@ class Tracks extends Model ord_c.c_name as ord_c_name, ord_c.c_pt_name as ord_c_pt_name"; } - $query .= " FROM t_vehicles AS v + $query .= + " FROM t_vehicles AS v INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid INNER JOIN t_vehicles_types AS t ON v.type_id = t.id INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id - LEFT JOIN " . self::T_TRACKS_ADDR . " AS tr_addr ON tr.latitude = tr_addr.lat AND tr.longitude = tr_addr.lng"; + LEFT JOIN " . + self::T_TRACKS_ADDR . + " AS tr_addr ON tr.latitude = tr_addr.lat AND tr.longitude = tr_addr.lng"; if (isset($filter["active_rates"])) { $query .= " INNER JOIN t_conf_rates as rate ON v.vendor_id = rate.vdr_id"; @@ -402,8 +405,10 @@ class Tracks extends Model $params[] = $filter["own_by_vdr_id"]; } if (isset($filter["active_rates"])) { - $query .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; - $query .= " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_ftl = ? AND rate.long_time = ?"; + $query .= + " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; + $query .= + " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_ftl = ? AND rate.long_time = ?"; array_push( $params, $filter["active_rates"]->origin_prov, @@ -434,242 +439,72 @@ class Tracks extends Model // Post-processing per row foreach ($list as $_list) { - $_list->vhc_sum_milleage = optional(DB::select( - "SELECT SUM(pre_milleage) as vhc_sum_milleage FROM " . self::T_TRACKS . " WHERE vhc_id = ?", - [$_list->vid] - ))[0]->vhc_sum_milleage ?? ""; + $_list->vhc_sum_milleage = + optional( + DB::select( + "SELECT SUM(pre_milleage) as vhc_sum_milleage FROM " . + self::T_TRACKS . + " WHERE vhc_id = ?", + [$_list->vid] + ) + )[0]->vhc_sum_milleage ?? ""; - $_list->lst_idle_at = optional(DB::select( - "SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine = ? AND vhc_id = ? AND crt_s >= ( - SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (?, ?) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 + $_list->lst_idle_at = + optional( + DB::select( + "SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine = ? AND vhc_id = ? AND crt_s >= ( + SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine IN (?, ?) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 ) ORDER BY id ASC LIMIT 1", - [self::STTS_EN_IDLING, $_list->vid, self::STTS_EN_STOPING, self::STTS_EN_MOVING, $_list->vid, $_list->lst_loc_crt_s] - ))[0]->crt_s ?? ""; + [ + self::STTS_EN_IDLING, + $_list->vid, + self::STTS_EN_STOPING, + self::STTS_EN_MOVING, + $_list->vid, + $_list->lst_loc_crt_s, + ] + ) + )[0]->crt_s ?? ""; - $_list->lst_stop_at = optional(DB::select( - "SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine = ? AND vhc_id = ? AND crt_s >= ( - SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (?, ?) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 + $_list->lst_stop_at = + optional( + DB::select( + "SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine = ? AND vhc_id = ? AND crt_s >= ( + SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine IN (?, ?) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 ) ORDER BY id ASC LIMIT 1", - [self::STTS_EN_STOPING, $_list->vid, self::STTS_EN_IDLING, self::STTS_EN_MOVING, $_list->vid, $_list->lst_loc_crt_s] - ))[0]->crt_s ?? ""; + [ + self::STTS_EN_STOPING, + $_list->vid, + self::STTS_EN_IDLING, + self::STTS_EN_MOVING, + $_list->vid, + $_list->lst_loc_crt_s, + ] + ) + )[0]->crt_s ?? ""; - $_list->lst_heartbeat = optional(DB::select( - "SELECT COUNT(id) as lst_heartbeat FROM " . self::T_TRACKS . " WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN ? AND ? LIMIT 1", - [$_list->vid, $now - 600, $now] - ))[0]->lst_heartbeat ?? ""; + $_list->lst_heartbeat = + optional( + DB::select( + "SELECT COUNT(id) as lst_heartbeat FROM " . + self::T_TRACKS . + " WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN ? AND ? LIMIT 1", + [$_list->vid, $now - 600, $now] + ) + )[0]->lst_heartbeat ?? ""; } return $list; } - // public static function listCurrentTracks($filter = []) - // { - // $now = time(); - // $params = []; - - // $query = "SELECT"; - // $query .= - // " v.id as vid,v.device_id,v.name as vhc_name,c.name as vhc_cat_name,t.name as vhc_type_name"; - // $query .= " ,v.nopol1,v.nopol2,v.nopol3,vd.fvhc_img"; - // $query .= " ,v.is_track_holiday,v.track_sch_d,v.track_sch_h,vd.speed_limit,v.crt as vhc_crt"; - // $query .= " ,client.id as client_group_id,client.c_name as client_group_name"; - // $query .= " ,tr.ignition,tr.stts_engine,tr.stts_gps,tr.stts_gsm"; - // $query .= " ,tr.pre_milleage,tr.sum_milleage,tr.vhc_milleage,v.sum_milleage AS vhc_sum_milleage_1"; - - // $query .= - // " ,tr.id AS lst_master_id,tr.latitude AS lst_lat,tr.longitude AS lst_lng,tr.speed AS lst_speed,tr.orientation AS lst_orientation"; - // $query .= " ,tr.crt AS lst_loc_crt,tr.crt_d AS lst_loc_crt_d,tr.crt_s AS lst_loc_crt_s"; - // $query .= - // " ,tr_addr.master_id AS lst_addr_master_id,tr_addr.country_text AS lst_country_text,tr_addr.state_text AS lst_state_text,tr_addr.city_text AS lst_city_text"; - // $query .= - // " ,tr_addr.district_text AS lst_district_text,tr_addr.village_text AS lst_village_text,tr_addr.postcode AS lst_postcode"; - // $query .= " ,tr_addr.streets AS lst_streets,tr_addr.fulladdress AS lst_fulladdress"; - - // $query .= " FROM t_vehicles AS v"; - // $query .= " INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid"; - // $query .= " INNER JOIN t_vehicles_types AS t ON v.type_id = t.id"; - // $query .= " INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id"; - // $query .= " LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id"; - // $query .= " LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id"; - // $query .= " LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id"; - // $query .= - // " LEFT JOIN t_gps_tracks_address AS tr_addr ON tr.latitude = tr_addr.lat and tr.longitude = tr_addr.lng"; - - // $query .= " WHERE v.dlt is null"; - // $query .= " AND tr.latitude != 0 AND tr.latitude is not null"; - // $query .= " GROUP BY v.id"; - // $query .= " ORDER BY tr.crt_d DESC"; - // $query .= " LIMIT 500;"; - - // $list = DB::select($query, $params); - // foreach ($list as $_list) { - // $_query = "SELECT sum_milleage as vhc_sum_milleage FROM t_vehicles WHERE id = ?"; - // $_query = DB::select($_query, [$_list->vid]); - // $_list->vhc_sum_milleage = $_query[0]->vhc_sum_milleage ?? 0; - - // $_query = " - // SELECT - // crt_s as lst_idle_at - // FROM - // t_gps_tracks - // WHERE - // stts_engine = 2 - // AND vhc_id = ? - // AND crt_s >= ( - // SELECT - // crt_s - // FROM - // t_gps_tracks - // WHERE - // stts_engine IN (0, 1) - // AND vhc_id = ? - // AND crt_s <= ? - // ORDER BY - // id DESC - // LIMIT 1 - // ) - // ORDER BY - // id ASC - // LIMIT 1"; - // $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); - // $_list->lst_idle_at = count($_query) == 0 ? "" : $_query[0]->lst_idle_at; - - // $_query = "SELECT crt_s as lst_stop_at FROM t_gps_tracks WHERE stts_engine = 0 AND vhc_id = ? AND crt_s >= ( - // SELECT crt_s FROM t_gps_tracks WHERE stts_engine IN (2,1) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 - // ) ORDER BY id ASC LIMIT 1 "; - // $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); - // $_list->lst_stop_at = count($_query) == 0 ? "" : $_query[0]->lst_stop_at; - - // $_query = - // " SELECT COUNT(id) as lst_heartbeat FROM t_gps_tracks WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN " . - // ($now - 10 * 60) . - // " AND " . - // $now . - // " LIMIT 1"; - // $_query = DB::select($_query, [$_list->vid]); - // $_list->lst_heartbeat = count($_query) == 0 ? "" : $_query[0]->lst_heartbeat; - // } - // return $list; - // } - - // public static function listCurrentTracks($filter = []) - // { - // $now = time(); - // $params = []; - - // $list = DB::select( - // " - // SELECT - // v.id as vid, v.device_id, v.name as vhc_name, - // c.name as vhc_cat_name, t.name as vhc_type_name, - // v.nopol1, v.nopol2, v.nopol3, vd.fvhc_img, - // v.is_track_holiday, v.track_sch_d, v.track_sch_h, - // vd.speed_limit, v.crt as vhc_crt, - // client.id as client_group_id, client.c_name as client_group_name, - // tr.ignition, tr.stts_engine, tr.stts_gps, tr.stts_gsm, - // tr.pre_milleage, tr.sum_milleage, tr.vhc_milleage, v.sum_milleage AS vhc_sum_milleage_1, - // tr.id AS lst_master_id, tr.latitude AS lst_lat, tr.longitude AS lst_lng, - // tr.speed AS lst_speed, tr.orientation AS lst_orientation, - // tr.crt AS lst_loc_crt, tr.crt_d AS lst_loc_crt_d, tr.crt_s AS lst_loc_crt_s, - // tr_addr.master_id AS lst_addr_master_id, - // tr_addr.country_text AS lst_country_text, tr_addr.state_text AS lst_state_text, - // tr_addr.city_text AS lst_city_text, tr_addr.district_text AS lst_district_text, - // tr_addr.village_text AS lst_village_text, tr_addr.postcode AS lst_postcode, - // tr_addr.streets AS lst_streets, tr_addr.fulladdress AS lst_fulladdress - // FROM t_vehicles AS v - // INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid - // INNER JOIN t_vehicles_types AS t ON v.type_id = t.id - // INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id - // LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id - // LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id - // LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id - // LEFT JOIN t_gps_tracks_address AS tr_addr ON tr.latitude = tr_addr.lat AND tr.longitude = tr_addr.lng - // WHERE v.dlt IS NULL - // AND tr.latitude != 0 AND tr.latitude IS NOT NULL - // GROUP BY v.id - // ORDER BY tr.crt_d DESC - // LIMIT 20 - // ", - // $params - // ); - - // foreach ($list as $_list) { - // $_list->vhc_sum_milleage = self::getVehicleMileage($_list->vid); - // $_list->lst_idle_at = self::getIdleAt($_list->vid, $_list->lst_loc_crt_s); - // $_list->lst_stop_at = self::getStopAt($_list->vid, $_list->lst_loc_crt_s); - // $_list->lst_heartbeat = self::getHeartbeat($_list->vid, $now); - // } - - // return $list; - // } - - private static function getVehicleMileage($vhc_id) - { - $res = DB::select("SELECT sum_milleage as vhc_sum_milleage FROM t_vehicles WHERE id = ? LIMIT 1", [ - $vhc_id, - ]); - return $res[0]->vhc_sum_milleage ?? 0; - } - - private static function getIdleAt($vhc_id, $ref_crt_s) - { - $res = DB::select( - " - SELECT crt_s as lst_idle_at - FROM t_gps_tracks - WHERE stts_engine = 2 - AND vhc_id = ? - AND crt_s >= ( - SELECT crt_s FROM t_gps_tracks - WHERE stts_engine IN (0, 1) AND vhc_id = ? AND crt_s <= ? - ORDER BY id DESC LIMIT 1 - ) - ORDER BY id ASC LIMIT 1 - ", - [$vhc_id, $vhc_id, $ref_crt_s] - ); - - return count($res) > 0 ? $res[0]->lst_idle_at : ""; - } - - private static function getStopAt($vhc_id, $ref_crt_s) - { - $res = DB::select( - " - SELECT crt_s as lst_stop_at - FROM t_gps_tracks - WHERE stts_engine = 0 AND vhc_id = ? - AND crt_s >= ( - SELECT crt_s FROM t_gps_tracks - WHERE stts_engine IN (2,1) AND vhc_id = ? AND crt_s <= ? - ORDER BY id DESC LIMIT 1 - ) - ORDER BY id ASC LIMIT 1 - ", - [$vhc_id, $vhc_id, $ref_crt_s] - ); - - return count($res) > 0 ? $res[0]->lst_stop_at : ""; - } - - private static function getHeartbeat($vhc_id, $now) - { - $start = $now - 600; - $res = DB::select( - " - SELECT COUNT(id) as lst_heartbeat - FROM t_gps_tracks - WHERE vhc_id = ? - AND action = 'heartbeat' - AND crt BETWEEN ? AND ? - LIMIT 1 - ", - [$vhc_id, $start, $now] - ); - - return count($res) > 0 ? $res[0]->lst_heartbeat : 0; - } - public static function lastMoveTracks($vid, $filter = []) { $now = time(); diff --git a/app/Models/Tracks_copy_last.php b/app/Models/Tracks_copy_last.php new file mode 100755 index 0000000..d8b7ede --- /dev/null +++ b/app/Models/Tracks_copy_last.php @@ -0,0 +1,1010 @@ +no signal, 2=>extremely weak signal 3=>very weak signal, 4=>good signal, 5=>strong signal + const STTS_GSM_DFT = 0; // default + const STTS_GSM_NO_SIGNAL = 1; + const STTS_GSM_BAD_SIGNAL = 2; + const STTS_GSM_WEAK_SIGNAL = 3; + const STTS_GSM_GOOD_SIGNAL = 4; + const STTS_GSM_STRONG_SIGNAL = 5; + + // type source + const SOURCE_GPS_TRACKER = 1; + const SOURCE_SMARTPHONE = 2; + + /** + * perlu tambahin filter untuk melihat tracking yang sesuai dengan vehiclenya aja + * karena ada case: + * device sudah sampai dilokasi pengantaran dan dimatikan, ketika dipakai lagi data tracking yang lama kelihatan dan loncat + * untuk mengatasi itu di service_tracking juga perlu validasi tambahan, entah seperti apa caranya + */ + + // public static function listCurrentTracks($filter = []) + // { + // $now = time(); + // $params = []; + + // $query = "SELECT"; + // $query .= + // " v.id as vid,v.device_id,v.name as vhc_name,c.name as vhc_cat_name,t.name as vhc_type_name"; + // $query .= " ,v.nopol1,v.nopol2,v.nopol3,vd.fvhc_img"; + // $query .= " ,v.is_track_holiday,v.track_sch_d,v.track_sch_h,vd.speed_limit,v.crt as vhc_crt"; + // $query .= " ,client.id as client_group_id,client.c_name as client_group_name"; + // $query .= " ,tr.ignition,tr.stts_engine,tr.stts_gps,tr.stts_gsm"; + // $query .= " ,tr.pre_milleage,tr.sum_milleage,tr.vhc_milleage,v.sum_milleage AS vhc_sum_milleage_1"; + + // // FRO + // // $query .= " ,(SELECT SUM(pre_milleage) FROM " . self::T_TRACKS . " WHERE vhc_id = v.id LIMIT 1) as vhc_sum_milleage"; + + // // $query .= " ,(SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine = " . self::STTS_EN_IDLING . " AND vhc_id = v.id AND crt_s >= ( + // // SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (" . self::STTS_EN_STOPING . "," . self::STTS_EN_MOVING . ") AND vhc_id = v.id AND crt_s <= tr.crt_s ORDER BY id DESC LIMIT 1 + // // ) ORDER BY id ASC LIMIT 1) as lst_idle_at"; + + // // $query .= " ,(SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine = " . self::STTS_EN_STOPING . " AND vhc_id = v.id AND crt_s >= ( + // // SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (" . self::STTS_EN_IDLING . "," . self::STTS_EN_MOVING . ") AND vhc_id = v.id AND crt_s <= tr.crt_s ORDER BY id DESC LIMIT 1 + // // ) ORDER BY id ASC LIMIT 1) as lst_stop_at"; + + // $query .= + // " ,tr.id AS lst_master_id,tr.latitude AS lst_lat,tr.longitude AS lst_lng,tr.speed AS lst_speed,tr.orientation AS lst_orientation"; + // $query .= " ,tr.crt AS lst_loc_crt,tr.crt_d AS lst_loc_crt_d,tr.crt_s AS lst_loc_crt_s"; + // $query .= + // " ,tr_addr.master_id AS lst_addr_master_id,tr_addr.country_text AS lst_country_text,tr_addr.state_text AS lst_state_text,tr_addr.city_text AS lst_city_text"; + // $query .= + // " ,tr_addr.district_text AS lst_district_text,tr_addr.village_text AS lst_village_text,tr_addr.postcode AS lst_postcode"; + // $query .= " ,tr_addr.streets AS lst_streets,tr_addr.fulladdress AS lst_fulladdress"; + + // // FRO + // // $query .= " ,(SELECT COUNT(id) FROM " . self::T_TRACKS . " WHERE vhc_id = v.id AND action = 'heartbeat' AND crt BETWEEN ".($now-(10*60))." AND ".$now." LIMIT 1) as lst_heartbeat"; // heartbeat last data on further 10 minutes + + // if (isset($filter["active_rates"])) { + // $query .= + // ",rate.vdr_id as rate_vdr_id,rate.vhc_type as rate_vhc_type,rate.origin_prov as rate_origin_prov,rate.dest_city as rate_dest_city,rate.dest_district as rate_dest_district"; + // $query .= + // ",rate.fast_time as rate_fast_time,rate.long_time as rate_long_time,rate.sell_kg as rate_sell_kg,rate.sell_cbm as rate_sell_cbm,rate.sell_ftl as rate_sell_ftl"; + // } + // if (isset($filter["get_order_data"])) { + // $query .= + // ",ord.id as ord_id,ord.code as ord_code,ord.status as ord_stts,ord.crt as ord_crt,ord_pck.pck_name as ord_pck_name,ord_pck.pck_addr as ord_pck_addr,ord_drop.drop_name as ord_drop_name,ord_drop.drop_addr as ord_drop_addr"; + // $query .= + // ",(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) ord_pck_ktname, (SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) ord_drop_ktname"; + // $query .= + // ",ord_drv.drv_name as ord_drv_name,ord_drv.drv_phone_val as ord_drv_phone_val,ord_drv.drv_phone2_val as ord_drv_phone2_val,ord_drv.drv_addr as ord_drv_addr"; + // $query .= ",ord_c.c_name as ord_c_name,ord_c.c_pt_name as ord_c_pt_name"; + // } + // $query .= " FROM t_vehicles AS v"; + // $query .= " INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid"; + // $query .= " INNER JOIN t_vehicles_types AS t ON v.type_id = t.id"; + // $query .= " INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id"; + // $query .= " LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id"; + // $query .= " LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id"; + // // get last updated row from many rows + // // $query .= " LEFT JOIN ( SELECT MAX(crt) max_crt, device_id FROM " . self::T_TRACKS . " WHERE latitude is not null AND longitude is not null GROUP BY device_id ORDER BY crt DESC ) AS tr1 ON (v.device_id = tr1.device_id)"; // cara lama berlaku utk gps tracker saja + // // // $query .= " LEFT JOIN ( SELECT MAX(crt) max_crt, device_id, vhc_id FROM " . self::T_TRACKS . " WHERE latitude is not null AND longitude is not null GROUP BY vhc_id ORDER BY crt DESC ) AS tr1 ON (v.id = tr1.vhc_id)"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI) + // // $query .= " LEFT JOIN " . self::T_TRACKS . " AS tr ON (tr.crt = tr1.max_crt)"; + // // get last updated tracking from updated table realtime + // // $query .= " LEFT JOIN db_trucking.t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id"; + // $query .= " LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id"; + // // $query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS tr_addr ON tr.id = tr_addr.master_id"; + + // //FRO + // $query .= + // " LEFT JOIN " . + // self::T_TRACKS_ADDR . + // " AS tr_addr ON tr.latitude = tr_addr.lat and tr.longitude = tr_addr.lng"; + + // if (isset($filter["active_rates"])) { + // // $query .= " INNER JOIN t_conf_rates as rate ON v.type_id = rate.vhc_type"; + // $query .= " INNER JOIN t_conf_rates as rate ON v.vendor_id = rate.vdr_id"; + // } + // if (isset($filter["get_order_data"])) { + // // the old way => only 1 order 1 vehicle + // $query .= " LEFT JOIN t_orders as ord ON v.ord_id = ord.id"; + // $query .= " LEFT JOIN t_orders_pickups as ord_pck ON v.ord_id = ord_pck.ord_id"; + // $query .= " LEFT JOIN t_orders_drops as ord_drop ON v.ord_id = ord_drop.ord_id"; + // $query .= " LEFT JOIN t_orders_drivers as ord_drv ON v.ord_id = ord_drv.ord_id"; + // $query .= " LEFT JOIN t_orders_clients as ord_c ON v.ord_id = ord_c.ord_id"; + + // // the new way => can handle 2 order in 1 vehicle + // // $query .= " LEFT JOIN t_orders_vehicles as ord_vhc ON v.id = ord_vhc.vhc_id"; + // // $query .= " LEFT JOIN t_orders as ord ON ord_vhc.ord_id = ord.id"; + // // $query .= " LEFT JOIN t_orders_pickups as ord_pck ON ord_vhc.ord_id = ord_pck.ord_id"; + // // $query .= " LEFT JOIN t_orders_drops as ord_drop ON ord_vhc.ord_id = ord_drop.ord_id"; + // // $query .= " LEFT JOIN t_orders_drivers as ord_drv ON ord_vhc.ord_id = ord_drv.ord_id"; + // // $query .= " LEFT JOIN t_orders_clients as ord_c ON ord_vhc.ord_id = ord_c.ord_id"; + // } + // $query .= " WHERE v.dlt is null"; + // // $query .= " AND tr.action IN ('location','alarm')"; // kalo gamau ngambil data heartbeat(idling) + // // $query .= " AND tr.device_id = v.device_id"; // cara lama berlaku utk gps tracker saja + // // $query .= " AND tr.vhc_id = v.id"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI) // bikin lemot + // $query .= " AND tr.latitude != 0 AND tr.latitude is not null"; + // if (isset($filter["status"])) { + // $query .= " AND v.status = ?"; + // $params[] = $filter["status"]; + // } + // if (isset($filter["is_in_ord"])) { + // $query .= " AND v.is_in_ord = ?"; + // $params[] = $filter["is_in_ord"]; + // } + // if (isset($filter["nopol1"]) && isset($filter["nopol2"]) && isset($filter["nopol3"])) { + // $query .= " AND v.nopol1 = ? AND v.nopol2 = ? AND v.nopol3 = ?"; + // array_push($params, $filter["nopol1"], $filter["nopol2"], $filter["nopol3"]); + // } + // if (isset($filter["vid"])) { + // $query .= " AND v.id = ?"; + // $params[] = $filter["vid"]; + // } + // if (isset($filter["vids"])) { + // if ($filter["vids"] && count($filter["vids"]) > 0) { + // $binds_vids = ""; + // foreach ($filter["vids"] as $k => $v) { + // $binds_vids .= "?,"; + // $params[] = $v; + // } + // if (substr($binds_vids, -1) === ",") { + // $binds_vids = substr($binds_vids, 0, -1); + // } + // $query .= " AND v.id IN ($binds_vids)"; + // } else { + // $query .= " AND v.id = ?"; + // $params[] = 0; + // } + // } + // if (isset($filter["own_by_vdr_id"])) { + // $query .= " AND v.vendor_id = ?"; + // $params[] = $filter["own_by_vdr_id"]; + // } + // if (isset($filter["active_rates"])) { + // // v1 + // // $query .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.dest_district != 0"; + // // $query .= " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_kg = ? AND rate.sell_cbm = ? AND rate.long_time = ?"; + // // array_push($params, $filter['active_rates']->origin_prov, $filter['active_rates']->dest_city, $filter['active_rates']->dest_district, $filter['active_rates']->sell_kg, $filter['active_rates']->sell_cbm, $filter['active_rates']->long_time); + // // v2 + // $query .= + // " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; + // $query .= + // " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_ftl = ? AND rate.long_time = ?"; + // array_push( + // $params, + // $filter["active_rates"]->origin_prov, + // $filter["active_rates"]->dest_city, + // $filter["active_rates"]->dest_district, + // $filter["active_rates"]->sell_ftl, + // $filter["active_rates"]->long_time + // ); + // } + // if (isset($filter["prefer_truck_type"])) { + // $query .= " AND v.type_id = ?"; + // $params[] = $filter["prefer_truck_type"]; + // } + // if (isset($filter["get_order_data"])) { + // if (isset($filter["client_id"])) { + // $query .= " AND ord_c.c_id = ?"; + // $params[] = $filter["client_id"]; + // } + // // $query .= " AND ord.status IN (22,4)"; + // } + // if (isset($filter["company"])) { + // $query .= " AND client.id = ?"; + // $params[] = $filter["company"]; + // } + + // // $query .= " AND v.id = 70"; + + // $query .= " GROUP BY v.id"; + // $query .= " ORDER BY tr.crt_d DESC"; + // $query .= " LIMIT 500;"; + + // // dd($query); + + // $list = DB::select($query, $params); + // foreach ($list as $_list) { + // $_query = + // " SELECT SUM(pre_milleage) as vhc_sum_milleage FROM " . self::T_TRACKS . " WHERE vhc_id = ?"; + // $_query = DB::select($_query, [$_list->vid]); + // $_list->vhc_sum_milleage = $_query[0]->vhc_sum_milleage; + + // $_query = + // " + // SELECT + // crt_s as lst_idle_at + // FROM + // " . + // self::T_TRACKS . + // " + // WHERE + // stts_engine = " . + // self::STTS_EN_IDLING . + // " + // AND vhc_id = ? + // AND crt_s >= ( + // SELECT + // crt_s + // FROM + // " . + // self::T_TRACKS . + // " + // WHERE + // stts_engine IN ( + // " . + // self::STTS_EN_STOPING . + // ", + // " . + // self::STTS_EN_MOVING . + // ") + // AND vhc_id = ? + // AND crt_s <= ? + // ORDER BY + // id DESC + // LIMIT 1 + // ) + // ORDER BY + // id ASC + // LIMIT 1"; + // $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); + // $_list->lst_idle_at = count($_query) == 0 ? "" : $_query[0]->lst_idle_at; + + // $_query = + // "SELECT crt_s as lst_stop_at FROM " . + // self::T_TRACKS . + // " WHERE stts_engine = " . + // self::STTS_EN_STOPING . + // " AND vhc_id = ? AND crt_s >= ( + // SELECT crt_s FROM " . + // self::T_TRACKS . + // " WHERE stts_engine IN (" . + // self::STTS_EN_IDLING . + // "," . + // self::STTS_EN_MOVING . + // ") AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 + // ) ORDER BY id ASC LIMIT 1 "; + // $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); + // $_list->lst_stop_at = count($_query) == 0 ? "" : $_query[0]->lst_stop_at; + + // $_query = + // " SELECT COUNT(id) as lst_heartbeat FROM " . + // self::T_TRACKS . + // " WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN " . + // ($now - 10 * 60) . + // " AND " . + // $now . + // " LIMIT 1"; + // $_query = DB::select($_query, [$_list->vid]); + // $_list->lst_heartbeat = count($_query) == 0 ? "" : $_query[0]->lst_heartbeat; + // } + // // em + // return $list; + // } + public static function listCurrentTracks($filter = []) + { + $now = time(); + $params = []; + + $query = "SELECT + v.id as vid, v.device_id, v.name as vhc_name, c.name as vhc_cat_name, t.name as vhc_type_name, + v.nopol1, v.nopol2, v.nopol3, vd.fvhc_img, + v.is_track_holiday, v.track_sch_d, v.track_sch_h, vd.speed_limit, v.crt as vhc_crt, + client.id as client_group_id, client.c_name as client_group_name, + tr.ignition, tr.stts_engine, tr.stts_gps, tr.stts_gsm, + tr.pre_milleage, tr.sum_milleage, tr.vhc_milleage, v.sum_milleage AS vhc_sum_milleage_1, + tr.id AS lst_master_id, tr.latitude AS lst_lat, tr.longitude AS lst_lng, + tr.speed AS lst_speed, tr.orientation AS lst_orientation, + tr.crt AS lst_loc_crt, tr.crt_d AS lst_loc_crt_d, tr.crt_s AS lst_loc_crt_s, + tr_addr.master_id AS lst_addr_master_id, tr_addr.country_text AS lst_country_text, + tr_addr.state_text AS lst_state_text, tr_addr.city_text AS lst_city_text, + tr_addr.district_text AS lst_district_text, tr_addr.village_text AS lst_village_text, + tr_addr.postcode AS lst_postcode, tr_addr.streets AS lst_streets, + tr_addr.fulladdress AS lst_fulladdress"; + + if (isset($filter["active_rates"])) { + $query .= ", + rate.vdr_id as rate_vdr_id, rate.vhc_type as rate_vhc_type, + rate.origin_prov as rate_origin_prov, rate.dest_city as rate_dest_city, + rate.dest_district as rate_dest_district, rate.fast_time as rate_fast_time, + rate.long_time as rate_long_time, rate.sell_kg as rate_sell_kg, + rate.sell_cbm as rate_sell_cbm, rate.sell_ftl as rate_sell_ftl"; + } + + if (isset($filter["get_order_data"])) { + $query .= ", + ord.id as ord_id, ord.code as ord_code, ord.status as ord_stts, ord.crt as ord_crt, + ord_pck.pck_name as ord_pck_name, ord_pck.pck_addr as ord_pck_addr, + ord_drop.drop_name as ord_drop_name, ord_drop.drop_addr as ord_drop_addr, + (SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) AS ord_pck_ktname, + (SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) AS ord_drop_ktname, + ord_drv.drv_name as ord_drv_name, ord_drv.drv_phone_val as ord_drv_phone_val, + ord_drv.drv_phone2_val as ord_drv_phone2_val, ord_drv.drv_addr as ord_drv_addr, + ord_c.c_name as ord_c_name, ord_c.c_pt_name as ord_c_pt_name"; + } + + $query .= + " FROM t_vehicles AS v + INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid + INNER JOIN t_vehicles_types AS t ON v.type_id = t.id + INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id + LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id + LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id + LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id + LEFT JOIN " . + self::T_TRACKS_ADDR . + " AS tr_addr ON tr.latitude = tr_addr.lat AND tr.longitude = tr_addr.lng"; + + if (isset($filter["active_rates"])) { + $query .= " INNER JOIN t_conf_rates as rate ON v.vendor_id = rate.vdr_id"; + } + + if (isset($filter["get_order_data"])) { + $query .= " + LEFT JOIN t_orders as ord ON v.ord_id = ord.id + LEFT JOIN t_orders_pickups as ord_pck ON v.ord_id = ord_pck.ord_id + LEFT JOIN t_orders_drops as ord_drop ON v.ord_id = ord_drop.ord_id + LEFT JOIN t_orders_drivers as ord_drv ON v.ord_id = ord_drv.ord_id + LEFT JOIN t_orders_clients as ord_c ON v.ord_id = ord_c.ord_id"; + } + + $query .= " WHERE v.dlt IS NULL AND tr.latitude != 0 AND tr.latitude IS NOT NULL"; + + if (isset($filter["status"])) { + $query .= " AND v.status = ?"; + $params[] = $filter["status"]; + } + if (isset($filter["is_in_ord"])) { + $query .= " AND v.is_in_ord = ?"; + $params[] = $filter["is_in_ord"]; + } + if (isset($filter["nopol1"], $filter["nopol2"], $filter["nopol3"])) { + $query .= " AND v.nopol1 = ? AND v.nopol2 = ? AND v.nopol3 = ?"; + array_push($params, $filter["nopol1"], $filter["nopol2"], $filter["nopol3"]); + } + if (isset($filter["vid"])) { + $query .= " AND v.id = ?"; + $params[] = $filter["vid"]; + } + if (isset($filter["vids"])) { + if ($filter["vids"] && count($filter["vids"]) > 0) { + $placeholders = rtrim(str_repeat("?,", count($filter["vids"])), ","); + $query .= " AND v.id IN ($placeholders)"; + $params = array_merge($params, $filter["vids"]); + } else { + $query .= " AND v.id = ?"; + $params[] = 0; + } + } + if (isset($filter["own_by_vdr_id"])) { + $query .= " AND v.vendor_id = ?"; + $params[] = $filter["own_by_vdr_id"]; + } + if (isset($filter["active_rates"])) { + $query .= + " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; + $query .= + " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_ftl = ? AND rate.long_time = ?"; + array_push( + $params, + $filter["active_rates"]->origin_prov, + $filter["active_rates"]->dest_city, + $filter["active_rates"]->dest_district, + $filter["active_rates"]->sell_ftl, + $filter["active_rates"]->long_time + ); + } + if (isset($filter["prefer_truck_type"])) { + $query .= " AND v.type_id = ?"; + $params[] = $filter["prefer_truck_type"]; + } + if (isset($filter["get_order_data"])) { + if (isset($filter["client_id"])) { + $query .= " AND ord_c.c_id = ?"; + $params[] = $filter["client_id"]; + } + } + if (isset($filter["company"])) { + $query .= " AND client.id = ?"; + $params[] = $filter["company"]; + } + + $query .= " GROUP BY v.id ORDER BY tr.crt_d DESC LIMIT 500"; + + $list = DB::select($query, $params); + + // Post-processing per row + foreach ($list as $_list) { + $_list->vhc_sum_milleage = + optional( + DB::select( + "SELECT SUM(pre_milleage) as vhc_sum_milleage FROM " . + self::T_TRACKS . + " WHERE vhc_id = ?", + [$_list->vid] + ) + )[0]->vhc_sum_milleage ?? ""; + + $_list->lst_idle_at = + optional( + DB::select( + "SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine = ? AND vhc_id = ? AND crt_s >= ( + SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine IN (?, ?) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 + ) ORDER BY id ASC LIMIT 1", + [ + self::STTS_EN_IDLING, + $_list->vid, + self::STTS_EN_STOPING, + self::STTS_EN_MOVING, + $_list->vid, + $_list->lst_loc_crt_s, + ] + ) + )[0]->crt_s ?? ""; + + $_list->lst_stop_at = + optional( + DB::select( + "SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine = ? AND vhc_id = ? AND crt_s >= ( + SELECT crt_s FROM " . + self::T_TRACKS . + " WHERE stts_engine IN (?, ?) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 + ) ORDER BY id ASC LIMIT 1", + [ + self::STTS_EN_STOPING, + $_list->vid, + self::STTS_EN_IDLING, + self::STTS_EN_MOVING, + $_list->vid, + $_list->lst_loc_crt_s, + ] + ) + )[0]->crt_s ?? ""; + + $_list->lst_heartbeat = + optional( + DB::select( + "SELECT COUNT(id) as lst_heartbeat FROM " . + self::T_TRACKS . + " WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN ? AND ? LIMIT 1", + [$_list->vid, $now - 600, $now] + ) + )[0]->lst_heartbeat ?? ""; + } + + return $list; + } + + // public static function listCurrentTracks($filter = []) + // { + // $now = time(); + // $params = []; + + // $query = "SELECT"; + // $query .= + // " v.id as vid,v.device_id,v.name as vhc_name,c.name as vhc_cat_name,t.name as vhc_type_name"; + // $query .= " ,v.nopol1,v.nopol2,v.nopol3,vd.fvhc_img"; + // $query .= " ,v.is_track_holiday,v.track_sch_d,v.track_sch_h,vd.speed_limit,v.crt as vhc_crt"; + // $query .= " ,client.id as client_group_id,client.c_name as client_group_name"; + // $query .= " ,tr.ignition,tr.stts_engine,tr.stts_gps,tr.stts_gsm"; + // $query .= " ,tr.pre_milleage,tr.sum_milleage,tr.vhc_milleage,v.sum_milleage AS vhc_sum_milleage_1"; + + // $query .= + // " ,tr.id AS lst_master_id,tr.latitude AS lst_lat,tr.longitude AS lst_lng,tr.speed AS lst_speed,tr.orientation AS lst_orientation"; + // $query .= " ,tr.crt AS lst_loc_crt,tr.crt_d AS lst_loc_crt_d,tr.crt_s AS lst_loc_crt_s"; + // $query .= + // " ,tr_addr.master_id AS lst_addr_master_id,tr_addr.country_text AS lst_country_text,tr_addr.state_text AS lst_state_text,tr_addr.city_text AS lst_city_text"; + // $query .= + // " ,tr_addr.district_text AS lst_district_text,tr_addr.village_text AS lst_village_text,tr_addr.postcode AS lst_postcode"; + // $query .= " ,tr_addr.streets AS lst_streets,tr_addr.fulladdress AS lst_fulladdress"; + + // $query .= " FROM t_vehicles AS v"; + // $query .= " INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid"; + // $query .= " INNER JOIN t_vehicles_types AS t ON v.type_id = t.id"; + // $query .= " INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id"; + // $query .= " LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id"; + // $query .= " LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id"; + // $query .= " LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id"; + // $query .= + // " LEFT JOIN t_gps_tracks_address AS tr_addr ON tr.latitude = tr_addr.lat and tr.longitude = tr_addr.lng"; + + // $query .= " WHERE v.dlt is null"; + // $query .= " AND tr.latitude != 0 AND tr.latitude is not null"; + // $query .= " GROUP BY v.id"; + // $query .= " ORDER BY tr.crt_d DESC"; + // $query .= " LIMIT 500;"; + + // $list = DB::select($query, $params); + // foreach ($list as $_list) { + // $_query = "SELECT sum_milleage as vhc_sum_milleage FROM t_vehicles WHERE id = ?"; + // $_query = DB::select($_query, [$_list->vid]); + // $_list->vhc_sum_milleage = $_query[0]->vhc_sum_milleage ?? 0; + + // $_query = " + // SELECT + // crt_s as lst_idle_at + // FROM + // t_gps_tracks + // WHERE + // stts_engine = 2 + // AND vhc_id = ? + // AND crt_s >= ( + // SELECT + // crt_s + // FROM + // t_gps_tracks + // WHERE + // stts_engine IN (0, 1) + // AND vhc_id = ? + // AND crt_s <= ? + // ORDER BY + // id DESC + // LIMIT 1 + // ) + // ORDER BY + // id ASC + // LIMIT 1"; + // $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); + // $_list->lst_idle_at = count($_query) == 0 ? "" : $_query[0]->lst_idle_at; + + // $_query = "SELECT crt_s as lst_stop_at FROM t_gps_tracks WHERE stts_engine = 0 AND vhc_id = ? AND crt_s >= ( + // SELECT crt_s FROM t_gps_tracks WHERE stts_engine IN (2,1) AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 + // ) ORDER BY id ASC LIMIT 1 "; + // $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); + // $_list->lst_stop_at = count($_query) == 0 ? "" : $_query[0]->lst_stop_at; + + // $_query = + // " SELECT COUNT(id) as lst_heartbeat FROM t_gps_tracks WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN " . + // ($now - 10 * 60) . + // " AND " . + // $now . + // " LIMIT 1"; + // $_query = DB::select($_query, [$_list->vid]); + // $_list->lst_heartbeat = count($_query) == 0 ? "" : $_query[0]->lst_heartbeat; + // } + // return $list; + // } + + // public static function listCurrentTracks($filter = []) + // { + // $now = time(); + // $params = []; + + // $list = DB::select( + // " + // SELECT + // v.id as vid, v.device_id, v.name as vhc_name, + // c.name as vhc_cat_name, t.name as vhc_type_name, + // v.nopol1, v.nopol2, v.nopol3, vd.fvhc_img, + // v.is_track_holiday, v.track_sch_d, v.track_sch_h, + // vd.speed_limit, v.crt as vhc_crt, + // client.id as client_group_id, client.c_name as client_group_name, + // tr.ignition, tr.stts_engine, tr.stts_gps, tr.stts_gsm, + // tr.pre_milleage, tr.sum_milleage, tr.vhc_milleage, v.sum_milleage AS vhc_sum_milleage_1, + // tr.id AS lst_master_id, tr.latitude AS lst_lat, tr.longitude AS lst_lng, + // tr.speed AS lst_speed, tr.orientation AS lst_orientation, + // tr.crt AS lst_loc_crt, tr.crt_d AS lst_loc_crt_d, tr.crt_s AS lst_loc_crt_s, + // tr_addr.master_id AS lst_addr_master_id, + // tr_addr.country_text AS lst_country_text, tr_addr.state_text AS lst_state_text, + // tr_addr.city_text AS lst_city_text, tr_addr.district_text AS lst_district_text, + // tr_addr.village_text AS lst_village_text, tr_addr.postcode AS lst_postcode, + // tr_addr.streets AS lst_streets, tr_addr.fulladdress AS lst_fulladdress + // FROM t_vehicles AS v + // INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid + // INNER JOIN t_vehicles_types AS t ON v.type_id = t.id + // INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id + // LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id + // LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id + // LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id + // LEFT JOIN t_gps_tracks_address AS tr_addr ON tr.latitude = tr_addr.lat AND tr.longitude = tr_addr.lng + // WHERE v.dlt IS NULL + // AND tr.latitude != 0 AND tr.latitude IS NOT NULL + // GROUP BY v.id + // ORDER BY tr.crt_d DESC + // LIMIT 20 + // ", + // $params + // ); + + // foreach ($list as $_list) { + // $_list->vhc_sum_milleage = self::getVehicleMileage($_list->vid); + // $_list->lst_idle_at = self::getIdleAt($_list->vid, $_list->lst_loc_crt_s); + // $_list->lst_stop_at = self::getStopAt($_list->vid, $_list->lst_loc_crt_s); + // $_list->lst_heartbeat = self::getHeartbeat($_list->vid, $now); + // } + + // return $list; + // } + + private static function getVehicleMileage($vhc_id) + { + $res = DB::select("SELECT sum_milleage as vhc_sum_milleage FROM t_vehicles WHERE id = ? LIMIT 1", [ + $vhc_id, + ]); + return $res[0]->vhc_sum_milleage ?? 0; + } + + private static function getIdleAt($vhc_id, $ref_crt_s) + { + $res = DB::select( + " + SELECT crt_s as lst_idle_at + FROM t_gps_tracks + WHERE stts_engine = 2 + AND vhc_id = ? + AND crt_s >= ( + SELECT crt_s FROM t_gps_tracks + WHERE stts_engine IN (0, 1) AND vhc_id = ? AND crt_s <= ? + ORDER BY id DESC LIMIT 1 + ) + ORDER BY id ASC LIMIT 1 + ", + [$vhc_id, $vhc_id, $ref_crt_s] + ); + + return count($res) > 0 ? $res[0]->lst_idle_at : ""; + } + + private static function getStopAt($vhc_id, $ref_crt_s) + { + $res = DB::select( + " + SELECT crt_s as lst_stop_at + FROM t_gps_tracks + WHERE stts_engine = 0 AND vhc_id = ? + AND crt_s >= ( + SELECT crt_s FROM t_gps_tracks + WHERE stts_engine IN (2,1) AND vhc_id = ? AND crt_s <= ? + ORDER BY id DESC LIMIT 1 + ) + ORDER BY id ASC LIMIT 1 + ", + [$vhc_id, $vhc_id, $ref_crt_s] + ); + + return count($res) > 0 ? $res[0]->lst_stop_at : ""; + } + + private static function getHeartbeat($vhc_id, $now) + { + $start = $now - 600; + $res = DB::select( + " + SELECT COUNT(id) as lst_heartbeat + FROM t_gps_tracks + WHERE vhc_id = ? + AND action = 'heartbeat' + AND crt BETWEEN ? AND ? + LIMIT 1 + ", + [$vhc_id, $start, $now] + ); + + return count($res) > 0 ? $res[0]->lst_heartbeat : 0; + } + + public static function lastMoveTracks($vid, $filter = []) + { + $now = time(); + $params = []; + $query = "SELECT"; + $query .= " v.id as vid,v.device_id,v.nopol1,v.nopol2,v.nopol3"; + $query .= " ,tr.id as master_id,tr.latitude,tr.longitude,tr.speed,tr.orientation"; + $query .= " + ,(tr.crt + ( 7 * 3600 )) AS lst_loc_crt + ,(tr.crt_d + ( 7 * 3600 )) AS lst_loc_crt_d + ,tr.crt_s AS lst_loc_crt_s"; + $query .= " ,tr.ignition,tr.stts_engine"; + $query .= " ,tr.pre_milleage,tr.sum_milleage,tr.vhc_milleage,v.sum_milleage AS vhc_sum_milleage_1"; + $query .= " ,addr.master_id AS addr_master_id,addr.crt AS addr_loc_crt"; + $query .= " ,addr.country_text, + addr.state_text,addr.city_text,addr.district_text,addr.village_text,addr.postcode,addr.streets,addr.postcode, + concat(addr.fulladdress,';',tr.id) as fulladdress + "; + $query .= " FROM t_vehicles AS v"; + // $query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.device_id = tr.device_id"; // cara lama berlaku utk gps tracker saja + $query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.id = tr.vhc_id"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI) + $query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS addr ON tr.id = addr.master_id"; + $query .= " WHERE v.dlt is null"; + $query .= " AND v.id = ?"; + array_push($params, $vid); + $query .= " AND tr.latitude is not null"; + $query .= " AND tr.longitude is not null"; + $query .= " AND tr.action in ('location')"; + + // last move based on date + // $query .= " AND tr.crt BETWEEN ? AND ?"; + // array_push($params, strtotime('-24 hours', $now), $now); + + if (isset($filter["start_date"]) && isset($filter["end_date"])) { + $query .= " AND tr.crt_d BETWEEN ? AND ?"; + array_push($params, $filter["start_date"], $filter["end_date"]); + } + + if (isset($filter["start_at"])) { + $query .= " AND tr.crt > ?"; + $params[] = $filter["start_at"]; + } + + // last move based on last count data + $query .= " GROUP BY tr.crt_d"; + $query .= " ORDER BY tr.crt_d DESC"; + // $query .= " ORDER BY tr.id DESC"; + // array_push($params, strtotime('-24 hours', $now), $now); + + if (isset($filter["limit"])) { + $query .= " LIMIT ?"; + $params[] = $filter["limit"] ?? 1000; + } + + $query .= " ;"; + $rawTracks = DB::select($query, $params); + $rawTracks = collect($rawTracks); + + $filtered = collect(); + $zeroBlock = collect(); + $tempBlock = collect(); + + $lastIndex = $rawTracks->count() - 1; + + foreach ($rawTracks as $i => $track) { + $isZero = $track->speed == 0; + + if ($i === $lastIndex) { + if ($isZero) { + $zeroBlock->push($track); + } else { + if ($zeroBlock->isNotEmpty()) { + $tempBlock = $zeroBlock; + $tempBlock->push($track); + + $zerosOnly = $tempBlock->filter(fn($t) => $t->speed == 0); + + if ($zerosOnly->count() === 1) { + $filtered->push($zerosOnly->first()); + } elseif ($zerosOnly->count() > 1) { + $filtered->push($zerosOnly->first()); + $filtered->push($zerosOnly->last()); + } + } else { + $filtered->push($track); + } + } + continue; + } + + if ($isZero) { + $zeroBlock->push($track); + } else { + if ($zeroBlock->isNotEmpty()) { + $filtered->push($zeroBlock->first()); + $zeroBlock = collect(); + } + $filtered->push($track); + } + } + + if ($zeroBlock->isNotEmpty() && $rawTracks->last()->speed == 0) { + if ($zeroBlock->count() === 1) { + $filtered->push($zeroBlock->first()); + } else { + $filtered->push($zeroBlock->first()); + $filtered->push($zeroBlock->last()); + } + } + + return $filtered->take(500); + } + + public static function nearestInCircle($lat, $lng, $rad, $filter = []) + { + $earth_rad = Helper::EARTH_RADIUS_M; + $t_gps_tracks = self::T_TRACKS; + + $select_select = ""; + $join_join = ""; + $where_where = ""; + + $params = [ + "lat1" => $lat, + "lat2" => $lat, + "lng" => $lng, + "v_status" => Vehicles::STTS_ACTIVE, + "v_is_in_ord" => Vehicles::IN_ORD_NO, + "rad" => $rad, + ]; + + if (isset($filter["active_rates"])) { + $select_select .= + ",rate.vdr_id as rate_vdr_id,rate.vhc_type as rate_vhc_type,rate.origin_prov as rate_origin_prov,rate.dest_city as rate_dest_city,rate.dest_district as rate_dest_district"; + $select_select .= + ",rate.fast_time as rate_fast_time,rate.long_time as rate_long_time,rate.sell_kg as rate_sell_kg,rate.sell_cbm"; + } + if (isset($filter["active_rates"])) { + // $join_join .= " INNER JOIN t_conf_rates as rate ON v.type_id = rate.vhc_type"; + $join_join .= " INNER JOIN t_conf_rates as rate ON v.vendor_id = rate.vdr_id"; + } + if (isset($filter["active_rates"])) { + // v1 + // $where_where .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.dest_district != 0"; + // $where_where .= " AND rate.origin_prov = :origin_prov AND (rate.dest_city = :dest_city OR rate.dest_district = :dest_district) AND rate.sell_kg = :sell_kg AND rate.sell_cbm = :sell_cbm AND rate.long_time = :long_time"; + // v2 + $where_where .= + " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; + $where_where .= + " AND rate.origin_prov = :origin_prov AND (rate.dest_city = :dest_city OR rate.dest_district = :dest_district) AND rate.sell_ftl = :sell_ftl AND rate.long_time = :long_time"; + $params["origin_prov"] = $filter["active_rates"]->origin_prov; + $params["dest_city"] = $filter["active_rates"]->dest_city; + $params["dest_district"] = $filter["active_rates"]->dest_district; + // v1 + // $params['sell_kg'] = $filter['active_rates']->sell_kg; + // $params['sell_cbm'] = $filter['active_rates']->sell_cbm; + // v2 + $params["sell_ftl"] = $filter["active_rates"]->sell_ftl; + $params["long_time"] = $filter["active_rates"]->long_time; + } + if (isset($filter["prefer_truck_type"])) { + $where_where .= " AND v.type_id = :prefer_truck_type"; + $params["prefer_truck_type"] = $filter["prefer_truck_type"]; + } + + $query = "SELECT v.*,tr.latitude,tr.longitude,tr.id as master_id + ,u.first_name as vendor_name,u.phone as vendor_phone,u.phone_code as vendor_phone_code,u.email as vendor_mail,u.fulladdress as vendor_addr + ,( $earth_rad * acos( cos( radians( :lat1 ) ) * cos( radians( tr.latitude ) ) + * cos( radians( tr.longitude ) - radians( :lng ) ) + sin( radians( :lat2 ) ) * sin(radians( tr.latitude )) ) ) AS distance + $select_select + FROM $t_gps_tracks as tr + INNER JOIN t_vehicles as v ON tr.vhc_id = v.id + INNER JOIN t_users as u ON v.vendor_id = u.id + -- get last updated row from many rows + LEFT JOIN ( SELECT MAX(crt) max_crt, vhc_id FROM $t_gps_tracks WHERE latitude is not null AND longitude is not null GROUP BY vhc_id ORDER BY crt DESC ) AS tr1 ON (v.id = tr1.vhc_id) + $join_join + WHERE v.dlt is null + AND v.status = :v_status + AND v.is_in_ord = :v_is_in_ord + AND tr.latitude is not null + AND tr.longitude != 0 + -- get last updated row from many rows + AND tr.crt = tr1.max_crt + $where_where + GROUP BY tr.vhc_id + HAVING distance <= :rad + -- ORDER BY distance ASC + ORDER BY tr.crt DESC + ;"; + return DB::select($query, $params); + } + + public static function addTracks($data) + { + $id = DB::table(self::T_TRACKS)->insertGetId($data); + return $id; + } + + public static function addTracksAddr($data) + { + $id = DB::table(self::T_TRACKS_ADDR)->insertGetId($data); + return $id; + } + + public static function listLogsGps($filter = []) + { + $params = []; + $where_where = ""; + $limit = ""; + + if (isset($filter["crt_greater_than"])) { + $where_where .= " AND crt > ?"; + $params[] = $filter["crt_greater_than"]; + } + + if (isset($filter["limit"])) { + $limit .= " LIMIT ?"; + $params[] = $filter["limit"]; + } + + return DB::select( + "SELECT + * + FROM " . + self::T_TRACKS . + " as tr + WHERE device_id is not null + AND device_id != 0 + " . + $where_where . + " + ORDER BY tr.crt DESC + " . + $limit . + " + ", + $params + ); + } + + public static function gpsLocsAddr($filter = []) + { + $params = []; + $select = ""; + $join = ""; + $where = ""; + $order_by = ""; + $group_by = ""; + $limit = ""; + + if (isset($filter["source"])) { + $where .= " AND tr.source = ?"; + $params[] = $filter["source"]; + } + + if (isset($filter["vhc_id"])) { + $where .= " AND tr.vhc_id = ?"; + $params[] = $filter["vhc_id"]; + } + + if (isset($filter["drv_id"])) { + $where .= " AND tr.drv_id = ?"; + $params[] = $filter["drv_id"]; + } + + if (isset($filter["group_by"])) { + $group_by .= " GROUP BY " . $filter["group_by"]; + } + if (isset($filter["order_by"])) { + $order_by .= " ORDER BY " . $filter["order_by"]; + } + if (isset($filter["limit"])) { + $limit .= " LIMIT " . $filter["limit"]; + } + + return DB::select( + "SELECT + tr.* + ,tr_addr.country_id,tr_addr.country_text,tr_addr.state_id,tr_addr.state_text,tr_addr.city_id,tr_addr.city_text + ,tr_addr.district_id,tr_addr.district_text,tr_addr.village_id,tr_addr.village_text,tr_addr.postcode,tr_addr.streets,tr_addr.fulladdress + ,tr_addr.stts_reverse_geo + $select + FROM t_gps_tracks as tr + LEFT JOIN t_gps_tracks_address as tr_addr ON tr.id = tr_addr.master_id + $join + WHERE tr.latitude is not null AND tr.longitude != 0 + $where + $group_by + $order_by + $limit + ;", + $params + ); + } +}