Files
old-svijetlastrana/server/router/tncroute/controller.go
2018-05-25 09:12:42 +02:00

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 = &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 {
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 = &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)
}