2018-04-25 13:16:36 +02:00
package tncroute
import (
"fmt"
"net/http"
"strconv"
"strings"
"sync"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/application/notificationservice"
"bitbucket.org/nemt/nemt-portal-api/application/tncservice"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/auth"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
2018-05-11 09:07:54 +02:00
"bitbucket.org/nemt/nemt-portal-api/server/validation"
2018-04-25 13:16:36 +02:00
"github.com/labstack/echo"
uuid "github.com/satori/go.uuid"
"google.golang.org/api/googleapi/transport"
urlshortener "google.golang.org/api/urlshortener/v1"
"github.com/gorilla/websocket"
)
var (
instance * controller
once sync . Once
upgrader = websocket . Upgrader { }
)
type controller struct {
cfg * config . Config
svc * applicationservice . Service
tnc * tncservice . Service
notification * notificationservice . Service
}
func controllerInstance ( cfg * config . Config , svc * applicationservice . Service , tnc * tncservice . Service , notification * notificationservice . Service ) * controller {
once . Do ( func ( ) {
instance = & controller {
cfg : cfg ,
svc : svc ,
tnc : tnc ,
notification : notification ,
}
} )
return instance
}
func ( c * controller ) handleSocket ( ctx echo . Context ) error {
ws , err := upgrader . Upgrade ( ctx . Response ( ) , ctx . Request ( ) , nil )
if err != nil {
return err
}
defer ws . Close ( )
for {
// Write
err := ws . WriteMessage ( websocket . TextMessage , [ ] byte ( "Hello, Client!" ) )
if err != nil {
ctx . Logger ( ) . Error ( err )
}
// Read
_ , msg , err := ws . ReadMessage ( )
if err != nil {
ctx . Logger ( ) . Error ( err )
}
fmt . Printf ( "%s\n" , msg )
}
}
func ( c * controller ) handleMessage ( ctx echo . Context ) error {
rideID := ctx . Param ( "ride_uuid" )
if rideID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "rideID param is mandatory" )
}
message := make ( map [ string ] string )
err := ctx . Bind ( & message )
if err != nil || message [ "message" ] == "" {
return routeutils . ResponseAPIValidationError ( ctx , "message body param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
notifications := make ( [ ] viewmodel . Notification , 0 )
notifications = append ( notifications , c . svc . Notification . GetNotification ( ride , "sms" , "A message to member" , message [ "message" ] , false , "message" ) )
notifications = append ( notifications , c . svc . Notification . GetNotification ( ride , "app" , "A message to member" , message [ "message" ] , false , "message" ) )
notifications , err = c . svc . Notification . SendNotifications ( notifications )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
return routeutils . ResponseAPIOK ( ctx , notifications )
}
func ( c * controller ) getURLShortened ( ride viewmodel . Ride ) ( string , error ) {
const (
url = "https://portal.bcbsinstitute.com/#/ride/%s/%s"
)
svc , err := urlshortener . New ( & http . Client {
Transport : & transport . APIKey { Key : c . cfg . GoogleShortener . APIKey } ,
} )
if err != nil {
return "" , err
}
userURL := fmt . Sprintf ( url , ride . UUID , ride . User . ID )
shortURL , err := svc . Url . Insert ( & urlshortener . Url {
Kind : "urlshortener#url" , // Not really needed
LongUrl : userURL ,
} ) . Do ( )
if err != nil {
return "" , err
}
return shortURL . Id , nil
}
func ( c * controller ) handleShare ( ctx echo . Context ) error {
const (
message = "%s shared a link with you for an upcoming ride: %s"
)
rideID := ctx . Param ( "ride_uuid" )
if rideID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "rideID param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
url , err := c . getURLShortened ( ride )
if err != nil {
fmt . Println ( "Error to short url: " , err )
}
notifications := make ( [ ] viewmodel . Notification , 0 )
notifications = append ( notifications , c . svc . Notification . GetNotification ( ride , "sms" , "A ride was shared with you" , fmt . Sprintf ( message , ride . CreatedUser . Name , url ) , false , "message" ) )
notifications = append ( notifications , c . svc . Notification . GetNotification ( ride , "email" , "A ride was shared with you" , fmt . Sprintf ( message , ride . CreatedUser . Name , url ) , false , "message" ) )
notifications = append ( notifications , c . svc . Notification . GetNotification ( ride , "app" , "A ride was shared with you" , fmt . Sprintf ( message , ride . CreatedUser . Name , url ) , false , "message" ) )
notifications , err = c . svc . Notification . SendNotifications ( notifications )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
return routeutils . ResponseAPIOK ( ctx , notifications )
}
func ( c * controller ) handleMessageDriver ( ctx echo . Context ) error {
rideID := ctx . Param ( "ride_uuid" )
if rideID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "rideID param is mandatory" )
}
message := make ( map [ string ] string )
err := ctx . Bind ( & message )
if err != nil || message [ "message" ] == "" {
return routeutils . ResponseAPIValidationError ( ctx , "message body param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
notifications := make ( [ ] viewmodel . Notification , 0 )
if ride . Status . Key == "accepted" || ride . Status . Key == "arrived" || ride . Status . Key == "pickedUp" {
notifications = append ( notifications , c . getDriverNotification ( ride , "sms" , "A message to driver" , message [ "message" ] , ride . Driver . PhoneNumber , * ride . CreatedUser . PhoneNumber ) )
notifications , err = c . svc . Notification . SendNotifications ( notifications )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
}
return routeutils . ResponseAPIOK ( ctx , notifications )
}
func ( c * controller ) handleList ( ctx echo . Context ) error {
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
entity , err := c . svc . Rides . GetAll ( user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ctx . Response ( ) . Header ( ) . Set ( "Content-Type" , "application/json" )
return routeutils . ResponseAPIOK ( ctx , entity )
}
func ( c * controller ) handle ( ctx echo . Context ) error {
var requestRide viewmodel . RideRequest
err := ctx . Bind ( & requestRide )
if err != nil {
fmt . Println ( err )
return routeutils . ResponseAPIValidationError ( ctx , "invalid parameters" )
}
user , err := c . svc . Users . GetByUUID ( requestRide . UserUUID , "US" )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
2018-05-11 09:07:54 +02:00
//Validate ride request
2018-05-25 09:12:42 +02:00
if validationErrors := validation . ValidateRide ( & requestRide , & user ) ; len ( validationErrors ) > 0 {
2018-05-11 09:07:54 +02:00
return routeutils . ResponseAPICustomValidationError ( ctx , "ride validation failed" , validationErrors )
}
2018-04-25 13:16:36 +02:00
createdUser , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
name := user . Name
names := strings . Split ( name , " " )
requestRide . Passenger . FirstName = names [ 0 ]
requestRide . Passenger . LastName = " "
requestRide . Passenger . PhoneNumber = * user . PhoneNumber
var resp viewmodel . RideRequest
if requestRide . TripType . Key != "from_visit_call" {
if requestRide . TripType . Key == "from_visit" {
newOrigin := requestRide . Origin
requestRide . Origin = requestRide . Destination
requestRide . Destination = newOrigin
}
if c . cfg . LyftProd . UserUUID != createdUser . ID {
resp , err = c . tnc . Lyft . RequestRide ( requestRide )
} else {
fmt . Println ( "In Production" )
resp , err = c . tnc . LyftProd . RequestRide ( requestRide )
}
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
if requestRide . TripType . Key == "from_visit" {
newOrigin := resp . Origin
resp . Origin = resp . Destination
resp . Destination = newOrigin
}
resp . RideID = strings . Replace ( resp . RideID , "s_" , "" , - 1 )
} else {
resp = requestRide
UUID , _ := uuid . NewV4 ( )
resp . RideID = UUID . String ( )
}
if resp . Status == "scheduled" || requestRide . TripType . Key == "from_visit_call" {
if requestRide . PickupTime == nil {
currentDate := time . Now ( )
requestRide . PickupTime = & currentDate
}
requestMS := ( requestRide . PickupTime . UnixNano ( ) / int64 ( time . Millisecond ) )
generateDate := time . Now ( )
generateMS := ( generateDate . UnixNano ( ) / int64 ( time . Millisecond ) )
resp . RequestAt = requestRide . PickupTime
resp . RequestAtMS = & requestMS
resp . GeneratedAt = & generateDate
resp . GeneratedAtMS = & generateMS
}
resp . Passenger . FirstName = names [ 0 ]
resp . Passenger . LastName = names [ len ( names ) - 1 ]
resp . Passenger . PhoneNumber = * user . PhoneNumber
if resp . Passenger . ImageURL == nil {
imageURL := " "
resp . Passenger . ImageURL = & imageURL
}
resp . UserUUID = requestRide . UserUUID
if requestRide . TripType . Key == "from_visit" {
resp . Origin . Name = requestRide . Destination . Name
resp . Origin . ID = requestRide . Destination . ID
resp . Destination . Name = requestRide . Origin . Name
resp . Destination . ID = requestRide . Origin . ID
} else {
resp . Origin . Name = requestRide . Origin . Name
resp . Origin . ID = requestRide . Origin . ID
resp . Destination . Name = requestRide . Destination . Name
resp . Destination . ID = requestRide . Destination . ID
}
resp . Distance = requestRide . Distance
resp . Duration = requestRide . Duration
resp . ETA = requestRide . ETA
resp . PickupTime = requestRide . PickupTime
resp . VisitDate = requestRide . VisitDate
resp . VisitTime = requestRide . VisitTime
resp . VisitExternalID = requestRide . VisitExternalID
resp . CreateUserUUID = createdUser . ID
resp . Visit . TripType = requestRide . TripType
if resp . TripType . Key == "from_visit_call" {
resp . Status = "willCall"
resp . Passenger . UserID = & resp . UserUUID
}
resp . TripType . Key = requestRide . TripType . Key
if requestRide . TripType . Key == "roundtrip" || requestRide . TripType . Key == "roundtrip_call" {
resp . TripType . Key = "to_visit"
} else if requestRide . TripType . Key == "from_visit_call" {
resp . TripType . Key = "from_visit_call"
}
entity , err := c . svc . Rides . Save ( resp )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
go func ( ) {
err = c . svc . Notification . SendNotification ( resp . Status , entity , resp )
if err != nil {
fmt . Println ( "Error to notify user: " , err . Error ( ) )
}
} ( )
if requestRide . TripType . Key == "roundtrip" || requestRide . TripType . Key == "roundtrip_call" {
newRide := requestRide
if requestRide . TripType . Key == "roundtrip" {
destination := newRide . Origin
newRide . Origin = newRide . Destination
newRide . Destination = destination
if requestRide . ReturnTime != nil {
newRide . PickupTime = requestRide . ReturnTime
}
scheduledRide := make ( map [ string ] interface { } )
scheduledRide [ "timestamp_ms" ] = requestRide . PickupTime . Unix ( )
newRide . ScheduledPickupRange = scheduledRide
newRide . Passenger . FirstName = names [ 0 ]
newRide . Passenger . LastName = " "
newRide . Passenger . PhoneNumber = * user . PhoneNumber
if c . cfg . LyftProd . UserUUID != createdUser . ID {
newRide , err = c . tnc . Lyft . RequestRide ( newRide )
} else {
fmt . Println ( "In Production" )
newRide , err = c . tnc . LyftProd . RequestRide ( newRide )
}
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
destination = newRide . Origin
newRide . Origin = newRide . Destination
newRide . Destination = destination
if newRide . Error != "" {
fmt . Println ( "Error to schedule a ride on lyft: " , newRide . Error , newRide . ErrorDescription )
} else {
fmt . Println ( "Ride Scheduled: " , newRide . Status )
}
newRide . TripType . Key = "from_visit"
} else {
newRide . TripType . Key = "from_visit_call"
newRide . Status = "willCall"
newRide . RideID = entity . UUID
}
newRide . Visit = entity . Visit
newRide . PickupTime = requestRide . ReturnTime
requestMS := ( newRide . PickupTime . UnixNano ( ) / int64 ( time . Millisecond ) )
generateDate := time . Now ( )
generateMS := ( generateDate . UnixNano ( ) / int64 ( time . Millisecond ) )
newRide . RequestAt = newRide . PickupTime
newRide . RequestAtMS = & requestMS
newRide . GeneratedAt = & generateDate
newRide . GeneratedAtMS = & generateMS
newRide . Passenger . FirstName = names [ 0 ]
newRide . Passenger . LastName = names [ len ( names ) - 1 ]
newRide . Passenger . PhoneNumber = * user . PhoneNumber
newRide . Passenger . UserID = & requestRide . UserUUID
if newRide . Passenger . ImageURL == nil {
imageURL := " "
newRide . Passenger . ImageURL = & imageURL
}
newRide . UserUUID = requestRide . UserUUID
newRide . Origin . Name = requestRide . Destination . Name
newRide . Origin . ID = requestRide . Destination . ID
newRide . Destination . Name = requestRide . Origin . Name
newRide . Destination . ID = requestRide . Origin . ID
newRide . Distance = requestRide . Distance
newRide . Duration = requestRide . Duration
newRide . ETA = requestRide . ETA
newRide . VisitDate = requestRide . VisitDate
newRide . VisitTime = requestRide . VisitTime
newRide . VisitExternalID = requestRide . VisitExternalID
newRide . CreateUserUUID = createdUser . ID
roudtripRide , err := c . svc . Rides . Save ( newRide )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
go func ( ) {
err = c . svc . Notification . SendNotification ( newRide . Status , roudtripRide , newRide )
if err != nil {
2018-05-25 09:12:42 +02:00
fmt . Println ( "Error notifying user: " , err . Error ( ) )
2018-04-25 13:16:36 +02:00
}
} ( )
}
ctx . Response ( ) . Header ( ) . Set ( "Content-Type" , "application/json" )
return routeutils . ResponseAPIOK ( ctx , entity )
}
func ( c * controller ) getDriverNotification ( ride viewmodel . Ride , notificationType string , subject string , message string , to string , from string ) viewmodel . Notification {
retVal := viewmodel . Notification {
Type : notificationType ,
Message : message ,
Subject : subject ,
Ride : ride ,
User : ride . User ,
CreatedUser : ride . CreatedUser ,
To : to ,
From : from ,
}
return retVal
}
func ( c * controller ) handleRawLyft ( ctx echo . Context ) error {
rideUUID := ctx . Param ( "ride_uuid" )
if rideUUID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "ride_uuid param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideUUID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
var lyftRide viewmodel . RideRequest
if ride . CreatedUser . ID != c . cfg . LyftProd . UserUUID {
lyftRide , err = c . tnc . Lyft . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
} else {
fmt . Println ( "In Production" )
lyftRide , err = c . tnc . LyftProd . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
}
if err != nil {
fmt . Println ( "Error getting lyft details: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
return routeutils . ResponseAPIOK ( ctx , lyftRide )
}
func ( c * controller ) handleRideETA ( ctx echo . Context ) error {
rideUUID := ctx . Param ( "ride_uuid" )
if rideUUID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "ride_uuid param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideUUID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
if ride . Status . Key == "accepted" || ride . Status . Key == "pickedUp" || ride . Status . Key == "arrived" {
var lyftRide viewmodel . RideRequest
if ride . CreatedUser . ID != c . cfg . LyftProd . UserUUID {
lyftRide , err = c . tnc . Lyft . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
} else {
fmt . Println ( "In Production" )
lyftRide , err = c . tnc . LyftProd . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
}
if err != nil {
fmt . Println ( "Error getting lyft details: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
ride . Route . Location = ride . Route . Origin
ride . Route . Location . Address = ""
ride . Route . Location . Name = ""
switch lyftRide . Status {
case "scheduled" :
ride . Route . ETA = ride . PickupTime . UnixNano ( ) / int64 ( time . Second )
case "accepted" :
if lyftRide . Origin . ETASeconds != nil {
ride . Route . ETA = * lyftRide . Origin . ETASeconds
} else {
ride . Route . ETA = 0
if c . cfg . App . Debug {
ride . Route . ETA = 350
}
}
case "arrived" , "pickedUp" :
if lyftRide . Destination . ETASeconds != nil {
ride . Route . ETA = * lyftRide . Destination . ETASeconds
} else {
ride . Route . ETA = 0
if c . cfg . App . Debug {
ride . Route . ETA = 350
}
}
}
if lyftRide . Location . Latitude != 0 && lyftRide . Location . Longitude != 0 {
ride . Route . Location = lyftRide . Location
}
}
return routeutils . ResponseAPIOK ( ctx , ride )
}
func ( c * controller ) handleCancel ( ctx echo . Context ) error {
var requestRide viewmodel . RideRequest
rideUUID := ctx . Param ( "ride_uuid" )
if rideUUID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "ride_uuid param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideUUID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
requestRide . RideID = ride . InternalID
if ride . Status . Key == "scheduled" && ! strings . Contains ( ride . InternalID , "s_" ) {
requestRide . RideID = "s_" + ride . InternalID
}
if ride . CreatedUser . ID != c . cfg . LyftProd . UserUUID {
err = c . tnc . Lyft . CancelRide ( requestRide )
if err != nil && err . Error ( ) == "ride_not_found" {
err = nil
}
} else {
fmt . Println ( "In Production" )
err = c . tnc . LyftProd . CancelRide ( requestRide )
}
if err != nil {
fmt . Println ( "Error: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
err = c . svc . Rides . UpdateStatus ( rideUUID , "canceled" )
if err != nil {
fmt . Println ( "Error: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
// ride.Status.Key = "canceled"
// go func() {
// err = c.svc.Notification.SendNotification(ride.Status.Key, ride, viewmodel.RideRequest{})
// if err != nil {
// fmt.Println("Error: ", err.Error())
// }
// }()
ctx . Response ( ) . Header ( ) . Set ( "Content-Type" , "application/json" )
return routeutils . ResponseNoContent ( ctx , nil )
}
func ( c * controller ) handleETA ( ctx echo . Context ) error {
sLat := ctx . Param ( "lat" )
if sLat == "" {
return routeutils . ResponseAPIValidationError ( ctx , "lat param is mandatory" )
}
sLog := ctx . Param ( "log" )
if sLog == "" {
return routeutils . ResponseAPIValidationError ( ctx , "log param is mandatory" )
}
sDestLat := ctx . Param ( "destlat" )
if sLat == "" {
return routeutils . ResponseAPIValidationError ( ctx , "lat param is mandatory" )
}
sDestLog := ctx . Param ( "destlong" )
if sLog == "" {
return routeutils . ResponseAPIValidationError ( ctx , "log param is mandatory" )
}
lat , err := strconv . ParseFloat ( strings . TrimSpace ( sLat ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "lat invalid" )
}
log , err := strconv . ParseFloat ( strings . TrimSpace ( sLog ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "log invalid" )
}
destlat , err := strconv . ParseFloat ( strings . TrimSpace ( sDestLat ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "destination lat invalid" )
}
destlog , err := strconv . ParseFloat ( strings . TrimSpace ( sDestLog ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "destination log invalid" )
}
params := map [ string ] interface { } { }
params [ "endLat" ] = destlat
params [ "endLng" ] = destlog
params [ "rideType" ] = "lyft"
resp , err := c . tnc . Lyft . GetCost ( lat , log , params )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
return routeutils . ResponseAPIOK ( ctx , resp )
}
func ( c * controller ) handleRide ( ctx echo . Context ) error {
rideUUID := ctx . Param ( "ride_uuid" )
if rideUUID == "" {
return routeutils . ResponseAPIValidationError ( ctx , "ride_uuid param is mandatory" )
}
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideUUID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
if ride . Status . Key == "accepted" || ride . Status . Key == "pickedUp" || ride . Status . Key == "arrived" {
var lyftRide viewmodel . RideRequest
if ride . CreatedUser . ID != c . cfg . LyftProd . UserUUID {
lyftRide , err = c . tnc . Lyft . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
} else {
fmt . Println ( "In Production" )
lyftRide , err = c . tnc . LyftProd . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
}
if err != nil {
fmt . Println ( "Error getting lyft details: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
ride . Route . Location = ride . Route . Origin
ride . Route . Location . Address = ""
ride . Route . Location . Name = ""
switch lyftRide . Status {
case "scheduled" :
ride . Route . ETA = ride . PickupTime . UnixNano ( ) / int64 ( time . Second )
case "accepted" :
if lyftRide . Origin . ETASeconds != nil {
ride . Route . ETA = * lyftRide . Origin . ETASeconds
} else {
ride . Route . ETA = 0
if c . cfg . App . Debug {
ride . Route . ETA = 350
}
}
case "arrived" :
if lyftRide . Destination . ETASeconds != nil {
ride . Route . ETA = * lyftRide . Destination . ETASeconds
} else {
ride . Route . ETA = 0
}
case "pickedUp" :
if lyftRide . Destination . ETASeconds != nil {
ride . Route . ETA = * lyftRide . Destination . ETASeconds
} else {
ride . Route . ETA = 0
if c . cfg . App . Debug {
ride . Route . ETA = 350
}
}
}
if lyftRide . Location . Latitude != 0 && lyftRide . Location . Longitude != 0 {
ride . Route . Location = lyftRide . Location
}
}
return routeutils . ResponseAPIOK ( ctx , ride )
}
func ( c * controller ) handleDrivers ( ctx echo . Context ) error {
sLat := ctx . Param ( "lat" )
if sLat == "" {
return routeutils . ResponseAPIValidationError ( ctx , "lat param is mandatory" )
}
sLog := ctx . Param ( "log" )
if sLog == "" {
return routeutils . ResponseAPIValidationError ( ctx , "log param is mandatory" )
}
lat , err := strconv . ParseFloat ( strings . TrimSpace ( sLat ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "lat invalid" )
}
log , err := strconv . ParseFloat ( strings . TrimSpace ( sLog ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "log invalid" )
}
resp , err := c . tnc . Lyft . GetDrivers ( lat , log )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
return routeutils . ResponseAPIOK ( ctx , resp )
}
func ( c * controller ) handleTypes ( ctx echo . Context ) error {
sLat := ctx . Param ( "lat" )
if sLat == "" {
return routeutils . ResponseAPIValidationError ( ctx , "lat param is mandatory" )
}
sLog := ctx . Param ( "log" )
if sLog == "" {
return routeutils . ResponseAPIValidationError ( ctx , "log param is mandatory" )
}
lat , err := strconv . ParseFloat ( strings . TrimSpace ( sLat ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "lat invalid" )
}
log , err := strconv . ParseFloat ( strings . TrimSpace ( sLog ) , 64 )
if err != nil {
return routeutils . ResponseAPIValidationError ( ctx , "log invalid" )
}
resp , err := c . tnc . Lyft . GetTypes ( lat , log , nil )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
return routeutils . ResponseAPIOK ( ctx , resp )
}
func ( c * controller ) handleReady ( ctx echo . Context ) error {
var rideUUID = ctx . Param ( "ride_uuid" )
user , err := auth . GetUserDetail ( ctx , c . cfg )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
ride , err := c . svc . Rides . GetByUUID ( rideUUID , user )
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
var nextRide viewmodel . Ride
if ride . TripType . Key == "from_visit_call" && ride . Status . Key == "willCall" {
nextRide = ride
} else if ride . Visit . TripType . Key == "roundtrip_call" && ride . TripType . Key == "to_visit" {
roundTripRide , err := c . svc . Rides . GetByVisitUUIDAndTripType ( ride . Visit . UUID , "from_visit_call" , user )
if err != nil {
fmt . Println ( "Error to get next ride: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
nextRide = roundTripRide
} else {
fmt . Println ( "Error on get next ride " )
return routeutils . ResponseAPINotFoundError ( ctx )
}
var lyftRide viewmodel . RideRequest
if ride . CreatedUser . ID != c . cfg . LyftProd . UserUUID {
lyftRide , err = c . tnc . Lyft . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
} else {
fmt . Println ( "In Production" )
lyftRide , err = c . tnc . LyftProd . GetRideDetails ( viewmodel . RideRequest { RideID : ride . InternalID } )
}
if err != nil {
fmt . Println ( "Error: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
lyftRide . RideID = ""
lyftRide . Destination = ride . Route . Destination
lyftRide . Origin = ride . Route . Origin
name := nextRide . User . Name
names := strings . Split ( name , " " )
lyftRide . Passenger . FirstName = names [ 0 ]
lyftRide . Passenger . LastName = " "
lyftRide . Passenger . PhoneNumber = * nextRide . User . PhoneNumber
lyftRide . RideType = "lyft"
if c . cfg . LyftProd . UserUUID != nextRide . CreatedUser . ID {
lyftRide , err = c . tnc . Lyft . RequestRide ( lyftRide )
} else {
fmt . Println ( "In Production" )
lyftRide , err = c . tnc . LyftProd . RequestRide ( lyftRide )
}
if err != nil {
return routeutils . HandleAPIError ( ctx , err )
}
currentTime := time . Now ( )
lyftRide . PickupTime = & currentTime
lyftRide . ReturnTime = & currentTime
nextRide . PickupTime = & currentTime
nextRide , err = c . svc . Rides . UpdateNewRide ( nextRide , lyftRide , user )
if err != nil {
fmt . Println ( "Error: " , err . Error ( ) )
return routeutils . HandleAPIError ( ctx , err )
}
go func ( ) {
err = c . svc . Notification . SendNotification ( lyftRide . Status , nextRide , lyftRide )
if err != nil {
fmt . Println ( "Error to notify user: " , err . Error ( ) )
}
} ( )
return routeutils . ResponseAPIOK ( ctx , nextRide )
2018-05-25 09:12:42 +02:00
}