876 lines
25 KiB
Go
876 lines
25 KiB
Go
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"
|
|
"bitbucket.org/nemt/nemt-portal-api/server/validation"
|
|
"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)
|
|
}
|
|
|
|
//Validate ride request
|
|
if validationErrors := validation.ValidateRide(&requestRide, &user); len(validationErrors) > 0 {
|
|
return routeutils.ResponseAPICustomValidationError(ctx, "ride validation failed", validationErrors)
|
|
}
|
|
|
|
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 = ¤tDate
|
|
}
|
|
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 {
|
|
fmt.Println("Error notifying user: ", err.Error())
|
|
}
|
|
}()
|
|
}
|
|
|
|
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 = ¤tTime
|
|
lyftRide.ReturnTime = ¤tTime
|
|
nextRide.PickupTime = ¤tTime
|
|
|
|
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)
|
|
}
|