cfgReadChar('system.oauth2_token'); $encryptionAlg = $savvyext->cfgReadChar('encryption.algorithm'); $encryptionKey = $savvyext->cfgReadChar('encryption.key'); $encryptionIV = $savvyext->cfgReadChar('encryption.iv'); $baseURL = $savvyext->cfgReadChar('system.api_url'); $db_host = $savvyext->cfgReadChar('database.host'); $db_name = $savvyext->cfgReadChar('database.name'); $db_user = $savvyext->cfgReadChar('database.user'); $db_pass = $savvyext->cfgReadChar('database.pass'); $db_port = $savvyext->cfgReadLong('database.port'); $connstr = "host=${db_host} port=${db_port} dbname=${db_name} user=${db_user} password=${db_pass}"; $conn = pg_connect($connstr); $member_id = 0; $country = 'SG'; $timezone = 1; // Asia/Singapore $distance = 2; // km $top_count = 15; #Grab, ComfortDelGro, GOJEK $transport_providers = [3,4,5]; $transport_providers = [4,5]; // Step 1: top 15 start locations $locations_start = []; $q = "SELECT COUNT(*) AS num, ROUND(b.latitude,2) AS lat, ROUND(b.longitude,2) AS lng "; $q.= " FROM parsedemail_item a LEFT JOIN address b ON b.id=a.location_start_id "; $q.= " WHERE b.timezone=${timezone} AND a.private='f' AND dup_id IS NULL "; $q.= " GROUP BY b.latitude, b.longitude ORDER BY num DESC LIMIT ${top_count}"; $r = pg_query($conn, $q); if ($r && pg_num_rows($r)) { $q1 = "select * from address where round(latitude,2)=%0.02f and round(longitude,2)=%0.02f order by random() limit 1"; while ($f=pg_fetch_row($r)) { $r1 = pg_query($conn, sprintf($q1,$f[1],$f[2])); if ($r1 && pg_num_rows($r1) && $f1=pg_fetch_assoc($r1)) { $locations_start[] = $f1; } } } // Step 2: top 15 end locations $locations_end = []; $q = "SELECT COUNT(*) AS num, ROUND(b.latitude,2) AS lat, ROUND(b.longitude,2) AS lng "; $q.= " FROM parsedemail_item a LEFT JOIN address b ON b.id=a.location_end_id "; $q.= " WHERE b.timezone=${timezone} AND a.private='f' AND dup_id IS NULL "; $q.= " GROUP BY b.latitude, b.longitude ORDER BY num DESC LIMIT ${top_count}"; $r = pg_query($conn, $q); if ($r && pg_num_rows($r)) { $q1 = "select * from address where round(latitude,2)=%0.02f and round(longitude,2)=%0.02f order by random() limit 1"; while ($f=pg_fetch_row($r)) { $r1 = pg_query($conn, sprintf($q1,$f[1],$f[2])); if ($r1 && pg_num_rows($r1) && $f1=pg_fetch_assoc($r1)) { $locations_end[] = $f1; } } } // Step 3: distance between locations (if makes sense to quote) $pairs = []; foreach ($locations_start as $location_start) { foreach ($locations_end as $location_end) { // Spheroid function in PHP to speed up $d = distanceBetweenTwoGpsCoordinates( $location_start["latitude"], $location_start["longitude"], $location_end["latitude"], $location_end["longitude"], "K" ); if ($d>$distance) { $pairs[] = [$location_start, $location_end]; } } } // Step 4: Schedule quotes $checkQuotes = []; QuoteApi::$job_name = $job_name; foreach ($pairs as list($location_start, $location_end)) { $origin_id = $location_start["id"]; $destination_id = $location_end["id"]; $origin = $location_start["address"]; $destination = $location_end["address"]; foreach ($transport_providers as $transport_provider) { $q = "SELECT * FROM quotes "; $q.= " WHERE location_start_id=${origin_id} AND location_end_id=${destination_id} "; $q.= " AND transport_provider_id=${transport_provider} AND cost>0 "; $q.= " AND completed>(current_date-1) "; $q.= " ORDER BY completed DESC LIMIT 1"; $r = pg_query($conn, $q); if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) { echo "[".date("Y-m-d H:i:s")."] Quote ".$f["cost"]." already exists ID #".$f["id"]."\n"; continue; } list($res,$id) = QuoteApi::schedule_quote($origin,$destination,$country,$member_id,$transport_provider); if ($res>0) { if ($res==2) { echo "[".date("Y-m-d H:i:s")."] Quote complete! ID #${id}\n"; } else if ($res==1) { echo "[".date("Y-m-d H:i:s")."] Scheduled quote ID #${id}\n"; $checkQuotes[] = $id; } else { echo "[".date("Y-m-d H:i:s")."] Unexpected result for ID #${id} ($res)\n"; } } else { echo "[".date("Y-m-d H:i:s")."] schedule_quote failed: ${res}.\n"; echo "[".date("Y-m-d H:i:s")."] $origin,$destination,$country,$member_id,$transport_provider\n"; } } } // Step 5: Check quotes foreach ($checkQuotes as $id) { list($res,$cost) = QuoteApi::check_quote($id); echo "[".date("Y-m-d H:i:s")."] Checking quote ID #${id} ($res) cost=${cost}\n"; } function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit) { //error_log("public function distanceBetweenTwoGpsCoordinates($lat1,$lon1,$lat2,$lon2,$unit)"); if (($lat1 == $lat2) && ($lon1 == $lon2)) { return 0; } $theta = $lon1 - $lon2; $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); $dist = acos($dist); $dist = rad2deg($dist); $miles = $dist * 60 * 1.1515; $unit = strtoupper($unit); if ($unit == "K") { return ($miles * 1.609344); } if ($unit == "N") { ($miles * 0.8684); } return $miles; } echo "[".date("Y-m-d H:i:s")."] ".$job_name." job complete.\n";