306 lines
12 KiB
PHP
306 lines
12 KiB
PHP
<?php
|
|
|
|
class Quotes {
|
|
|
|
const BASE_SQL_DATA = "SELECT a.*,ls.address AS location_start,ls.latitude AS location_start_lat,ls.longitude AS location_start_lng,ls.timezone AS location_start_tz,ls.geocoding_date AS location_geocoding_date,le.address AS location_end,le.latitude AS location_end_lat,le.longitude AS location_end_lng ";
|
|
const BASE_SQL_FROM = " FROM quotes a, address ls, address le WHERE ls.id=a.location_start_id AND le.id=a.location_end_id";
|
|
|
|
const VENDOR_UBER = 1;
|
|
const VENDOR_LYFT = 2;
|
|
const VENDOR_GRAB = 3;
|
|
const VENDOR_COMFORTDELGRO = 4; // ComfortDelGro
|
|
const VENDOR_GOJEK = 5;
|
|
const VENDOR_TURO = 6;
|
|
const VENDOR_GETAROUND = 7;
|
|
const VENDOR_AUTOCAB = 8;
|
|
|
|
public static function getById($db, $id) {
|
|
syslog(LOG_WARNING,"Quote::getById(\$db, $id)");
|
|
Logger::debug("Quote::getById(\$db, $id)");
|
|
$result = [];
|
|
$q = Quotes::BASE_SQL_DATA . Quotes::BASE_SQL_FROM . " AND a.id=${id} ";
|
|
$r = pg_query($db, $q);
|
|
//syslog(LOG_WARNING,$q);
|
|
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
|
$f["location_start"] = html_entity_decode ($f["location_start"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
|
$f["location_end"] = html_entity_decode ($f["location_end"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
|
$result = $f;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
public static function getByOriginDestinationId($db, $origin, $destination, $tpid, $limit, $offset) {
|
|
syslog(LOG_WARNING,"Quote::getByOriginDestinationId(\$db, $origin, $destination, $tpid, $limit, $offset)");
|
|
$results = [];
|
|
$total = 0;
|
|
$db_origin = pg_escape_string(strtolower($origin));
|
|
$db_destination = pg_escape_string(strtolower($destination));
|
|
$q = "SELECT count(*) ".Quotes::BASE_SQL_FROM." AND lower(ls.address)='${db_origin}'
|
|
AND lower(le.address)='${db_destination}'";
|
|
if ($tpid>0) {
|
|
$q.= " AND a.transport_provider_id=${tpid}";
|
|
}
|
|
$q.= " AND a.cost>0";
|
|
$r = pg_query($db, $q);
|
|
if ($r && pg_num_rows($r) && $f=pg_fetch_row($r)) {
|
|
$total = $f[0];
|
|
}
|
|
if ($total>0 && $offset<$total) {
|
|
$q = Quotes::BASE_SQL_DATA . Quotes::BASE_SQL_FROM . " AND lower(ls.address)='${db_origin}' ";
|
|
$q.= " AND lower(le.address)='${db_destination}' ".($tpid>0?" AND a.transport_provider_id=${tpid}":"");
|
|
$q.= " AND a.cost>0";
|
|
$q.= " ORDER BY a.created DESC LIMIT ${limit} OFFSET ${offset}";
|
|
$r = pg_query($db, $q);
|
|
if ($r && pg_num_rows($r)) {
|
|
while ($f=pg_fetch_assoc($r)) {
|
|
$f["location_start"] = html_entity_decode ($f["location_start"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
|
$f["location_end"] = html_entity_decode ($f["location_end"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
|
$results[] = $f;
|
|
}
|
|
}
|
|
}
|
|
return array($total, $results);
|
|
}
|
|
|
|
public static function getLastQuoteByOriginDestinationId($db, $origin, $destination, $tpid, $cacheTimeout = 300) {
|
|
$db_origin = pg_escape_string(strtolower($origin));
|
|
$db_destination = pg_escape_string(strtolower($destination));
|
|
|
|
$q = Quotes::BASE_SQL_DATA . Quotes::BASE_SQL_FROM;
|
|
$q.= " AND a.completed > now() - ( ${cacheTimeout} ||' seconds')::interval ";
|
|
$q.= " AND lower(ls.address)='${db_origin}' ";
|
|
$q.= " AND lower(le.address)='${db_destination}' ".($tpid>0?" AND a.transport_provider_id=${tpid}":"");
|
|
$q.= " AND a.cost>0";
|
|
$q.= " ORDER BY a.created DESC LIMIT 1 OFFSET 0";
|
|
$result = NULL;
|
|
$r = pg_query($db, $q);
|
|
if ( $r && pg_num_rows( $r ) && $f = pg_fetch_assoc( $r ) ) {
|
|
$result = $f;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
public static function getLastQuoteByOriginDestinationCoordinates($db, $origin, $destination, $tpId, $cacheTimeout = 300) {
|
|
if (!is_array($origin) || !is_array($destination)
|
|
|| !isset($origin['lat'])|| !isset($origin['lng'])
|
|
|| !isset($destination['lat'])|| !isset($destination['lng'])
|
|
) {
|
|
return NULL;
|
|
}
|
|
|
|
$origin_lat = $origin['lat'];
|
|
$origin_lng = $origin['lng'];
|
|
$destination_lat = $destination['lat'];
|
|
$destination_lng = $destination['lng'];
|
|
|
|
$q = Quotes::BASE_SQL_DATA . Quotes::BASE_SQL_FROM;
|
|
$q.= " AND a.completed > now() - ( ${cacheTimeout} ||' seconds')::interval ";
|
|
$q.= " AND ls.geometry = ST_SetSRID(ST_MakePoint( ${origin_lng}, ${origin_lat}), 4326)::geography ";
|
|
$q.= " AND le.geometry = ST_SetSRID(ST_MakePoint( ${destination_lng}, ${destination_lat}), 4326)::geography";
|
|
$q.= ($tpId>0?" AND a.transport_provider_id=${tpId}":"");
|
|
$q.= " AND a.cost>0";
|
|
$q.= " ORDER BY a.created DESC LIMIT 1 OFFSET 0";
|
|
$result = NULL;
|
|
$r = pg_query($db, $q);
|
|
if ( $r && pg_num_rows( $r ) && $f = pg_fetch_assoc( $r ) ) {
|
|
$result = $f;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
public static function getByQuoteGroupId($db, $id) {
|
|
$q = Quotes::BASE_SQL_DATA . Quotes::BASE_SQL_FROM . " AND quote_group_id>0 AND quote_group_id=".((int)$id);
|
|
$r = pg_query($db, $q);
|
|
if ($r && pg_num_rows($r)) {
|
|
$results = [];
|
|
while ($f=pg_fetch_assoc($r)) {
|
|
$f["location_start"] = html_entity_decode ($f["location_start"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
|
$f["location_end"] = html_entity_decode ($f["location_end"],ENT_QUOTES|ENT_HTML5,"UTF-8");
|
|
$results[] = $f;
|
|
}
|
|
return array($results, NULL);
|
|
}
|
|
return array(NULL,pg_last_error($db));
|
|
}
|
|
|
|
public static function create($db, $data) {
|
|
syslog(LOG_WARNING,'Quote::create($db, $data)');
|
|
$location_start_id = Address::getAddress($db, $data, "location_start");
|
|
$location_end_id = Address::getAddress($db, $data, "location_end");
|
|
if ($location_start_id==NULL || $location_end_id==NULL) {
|
|
return array(NULL,"Failed to save address");
|
|
}
|
|
$q = "INSERT INTO quotes (transport_provider_id,automation_id,member_id,location_start_id,location_end_id, quote_group_id, prefill, pool) ";
|
|
$q.= " VALUES(".((int)$data["transport_provider_id"]).",".((int)$data["automation_id"]).",".((int)$data["member_id"]).",";
|
|
$q.= "${location_start_id},${location_end_id},".((int)$data["quote_group_id"]).",".($data["prefill"]!='t'?"'f'":"'t'");
|
|
$q.= ",".($data["pool"]!=2?"1":"2");
|
|
$q.= ") RETURNING id";
|
|
$log = [
|
|
'message' => 'insert quote',
|
|
'data' =>$data,
|
|
'query' =>$q
|
|
];
|
|
Logger::debug($log);
|
|
syslog(LOG_WARNING,'***************************************************************************');
|
|
syslog(LOG_WARNING,$q);
|
|
syslog(LOG_WARNING,'***************************************************************************');
|
|
$r = pg_query($db, $q);
|
|
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
|
return [Quotes::getById($db, $f["id"]),NULL];
|
|
}
|
|
syslog(LOG_WARNING,pg_last_error($db));
|
|
return [NULL,pg_last_error($db)];
|
|
}
|
|
|
|
public static function update($db, $data) {
|
|
syslog(LOG_WARNING,'Quotes::update(): '.json_encode($data));
|
|
// cost_raw='".$data["cost_raw"]."',
|
|
// created='".$data["created"]."',
|
|
// member_id='".$data["member_id"]."'
|
|
$q = "UPDATE quotes SET
|
|
transport_provider_id=".((int)$data["transport_provider_id"]).",
|
|
automation_id=".((int)$data["automation_id"]).",
|
|
cost=".((float)$data["cost"]).",
|
|
completed='".$data["completed"]."',
|
|
travel_date='".$data["travel_date"]."',
|
|
location_start_id=".$data["location_start_id"].",
|
|
location_end_id=".$data["location_end_id"]."
|
|
WHERE id='".$data["id"]."'";
|
|
//error_log($q);
|
|
syslog(LOG_WARNING,$q);
|
|
$r = pg_query($db, $q);
|
|
/* $log = [
|
|
'affected_row' => pg_affected_rows($r),
|
|
'message' => 'update quote',
|
|
'data' =>$data,
|
|
'query' =>$q
|
|
];
|
|
Logger::debug($log); */
|
|
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
|
return array(self::getById($db, $data["id"]),NULL);
|
|
}
|
|
return array(NULL, pg_last_error($db));
|
|
}
|
|
|
|
public static function getLegStepQuoteBySID($db, $sid) {
|
|
$q = "SELECT * FROM leg_step_quote WHERE google_directions_leg_step_id=".((int)$sid);
|
|
$r = pg_query($db, $q);
|
|
if ($r && pg_num_rows($r) && $f=pg_fetch_assoc($r)) {
|
|
return [$f, NULL];
|
|
}
|
|
return [NULL, pg_last_error($db)];
|
|
}
|
|
|
|
public static function deeplink($db, $quote) {
|
|
syslog(LOG_WARNING,"Quote::deeplink(\$db, \$quote)");
|
|
Logger::debug("Quote::deeplink(\$db, \$quote)");
|
|
$url = "";
|
|
switch ($quote["transport_provider_id"]) {
|
|
case Quotes::VENDOR_UBER: // Uber
|
|
// https://developer.uber.com/docs/riders/ride-requests/tutorials/deep-links/introduction
|
|
$url = sprintf("uber://?client_id=IrcAu0gxX7EsPKWg3QJe8reR5Q8w1jDm&action=setPickup&pickup[latitude]=%f&pickup[longitude]=%f&dropoff[latitude]=%f&dropoff[longitude]=%f",
|
|
$quote["location_start_lat"], $quote["location_start_lng"],
|
|
$quote["location_end_lat"], $quote["location_end_lng"]
|
|
);
|
|
break;
|
|
case Quotes::VENDOR_LYFT: // Lyft
|
|
// https://developer.lyft.com/docs/deeplinking
|
|
// &partner=GZbtPgh56RQb
|
|
// &credits=<my_custom_promo_code>
|
|
$url = sprintf("lyft://ridetype?id=lyft&pickup[latitude]=%f&pickup[longitude]=%f&destination[latitude]=%f&destination[longitude]=%f",
|
|
$quote["location_start_lat"], $quote["location_start_lng"],
|
|
$quote["location_end_lat"], $quote["location_end_lng"]
|
|
);
|
|
break;
|
|
case Quotes::VENDOR_GRAB: // Grab
|
|
// TODO: rotate the sources!
|
|
$url = sprintf("grab://open?screenType=BOOKING&sourceId=raZbevC7RB&sourceAppName=SingaporeAir&dropOffLatitude=%f&dropOffLongitude=%f&pickUpLatitude=%f&pickUpLongitude=%f",
|
|
$quote["location_end_lat"], $quote["location_end_lng"],
|
|
$quote["location_start_lat"], $quote["location_start_lng"]
|
|
);
|
|
break;
|
|
case Quotes::VENDOR_COMFORTDELGRO: // ComfortDelGro
|
|
$url = sprintf("ComfortDelGroTaxi:///?action=setBooking&endingLat=%f&endingLong=%f&startingLat=%f&startingLong=%f",
|
|
$quote["location_end_lat"], $quote["location_end_lng"],
|
|
$quote["location_start_lat"], $quote["location_start_lng"]
|
|
);
|
|
break;
|
|
case Quotes::VENDOR_GOJEK: // Gojek
|
|
$url = sprintf("gojek://sggocar/gocar?product_id=car&pickup_latitude=%f&pickup_longitude=%f&dropoff_latitude=%f&dropoff_longitude=%f",
|
|
$quote["location_start_lat"], $quote["location_start_lng"],
|
|
$quote["location_end_lat"], $quote["location_end_lng"]
|
|
);
|
|
break;
|
|
}
|
|
//syslog(LOG_WARNING,"url=${url}");
|
|
return $url;
|
|
}
|
|
|
|
public static function checkQuote($id) {
|
|
global $savvyext;
|
|
$httpAuthToken = $savvyext->cfgReadChar('system.automation_api_token');
|
|
$automation_api_url = $savvyext->cfgReadChar('system.automation_api_url');
|
|
|
|
$url = $automation_api_url."automation-job/" . $id;
|
|
$opts = array(
|
|
'http' => array(
|
|
'method' => "GET",
|
|
'header' =>
|
|
"Content-Type: application/json\r\n" .
|
|
"Accept: application/json\r\n" .
|
|
"Authorization: Server-Token ${httpAuthToken}\r\n"
|
|
),
|
|
"ssl" => array(
|
|
"verify_peer"=>false,
|
|
"verify_peer_name"=>false,
|
|
)
|
|
);
|
|
$context = stream_context_create($opts);
|
|
$body = file_get_contents($url, false, $context);
|
|
$quote = json_decode($body,true);
|
|
if (is_array($quote) && isset($quote["id"])) {
|
|
return array($quote, NULL);
|
|
} else if (is_array($quote) && isset($quote["message"])) {
|
|
$body = $quote["message"];
|
|
error_log(isset($quote["error"]) ? json_encode($quote["error"]) : $quote["message"]);
|
|
}
|
|
return array(NULL, $body);
|
|
}
|
|
|
|
public static function getQuoteDetails($id) {
|
|
global $savvyext;
|
|
$httpAuthToken = $savvyext->cfgReadChar('system.automation_api_token');
|
|
$automation_api_url = $savvyext->cfgReadChar('system.automation_api_url');
|
|
|
|
$url = $automation_api_url."automation-job-detail/" . $id;
|
|
$opts = array(
|
|
'http' => array(
|
|
'method' => "GET",
|
|
'header' =>
|
|
"Content-Type: application/json\r\n" .
|
|
"Accept: application/json\r\n" .
|
|
"Authorization: Server-Token ${httpAuthToken}\r\n"
|
|
),
|
|
"ssl" => array(
|
|
"verify_peer"=>false,
|
|
"verify_peer_name"=>false,
|
|
)
|
|
);
|
|
$context = stream_context_create($opts);
|
|
$body = file_get_contents($url, false, $context);
|
|
$details = json_decode($body,true);
|
|
if (is_array($details) && count($details)>0 && isset($details[0]["id"])) {
|
|
return array($details, NULL);
|
|
} else if (is_array($details) && isset($details["message"])) {
|
|
$body = $details["message"];
|
|
error_log(isset($details["error"]) ? json_encode($details["error"]) : $details["message"]);
|
|
}
|
|
return array(NULL, $body);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// vi:ts=2
|
|
|