301 lines
8.8 KiB
Go
301 lines
8.8 KiB
Go
package externalroute
|
|
|
|
import (
|
|
"fmt"
|
|
"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/config"
|
|
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
|
|
"github.com/labstack/echo"
|
|
)
|
|
|
|
var (
|
|
instance *controller
|
|
once sync.Once
|
|
)
|
|
|
|
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) 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) handleCancel(ctx echo.Context) error {
|
|
var rideUUID = ctx.Param("ride_uuid")
|
|
var userUUID = ctx.Param("user_uuid")
|
|
|
|
ride, err := c.svc.Rides.GetByUUIDAndUserUUID(rideUUID, userUUID)
|
|
if err != nil {
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
authUser, err := c.svc.Users.GetByUUID(ride.CreatedUser.ID, "")
|
|
if err != nil {
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
lyftRide := viewmodel.RideRequest{RideID: ride.InternalID}
|
|
if ride.Status.Key == "scheduled" && !strings.Contains(ride.InternalID, "s_") {
|
|
lyftRide.RideID = "s_" + ride.InternalID
|
|
}
|
|
|
|
if authUser.Test {
|
|
if err = c.tnc.Lyft.CancelRide(lyftRide); err != nil {
|
|
if err.Error() != "ride_not_found" {
|
|
fmt.Println("Error to cancel with Lyft: ", err.Error())
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
}
|
|
} else {
|
|
fmt.Println("In Production")
|
|
if err = c.tnc.LyftProd.CancelRide(lyftRide); err != nil {
|
|
fmt.Println("Error to cancel with Lyft: ", 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"
|
|
|
|
// err = c.svc.Notification.SendNotification(ride.Status.Key, ride, viewmodel.RideRequest{})
|
|
// if err != nil {
|
|
// fmt.Println("Error to notify: ", err.Error())
|
|
// }
|
|
|
|
ctx.Response().Header().Set("Content-Type", "application/json")
|
|
return routeutils.ResponseNoContent(ctx, nil)
|
|
}
|
|
|
|
func (c *controller) handleMessage(ctx echo.Context) error {
|
|
var rideUUID = ctx.Param("ride_uuid")
|
|
var userUUID = ctx.Param("user_uuid")
|
|
|
|
ride, err := c.svc.Rides.GetByUUIDAndUserUUID(rideUUID, userUUID)
|
|
if err != nil {
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
message := make(map[string]string)
|
|
err = ctx.Bind(&message)
|
|
if err != nil || message["message"] == "" {
|
|
return routeutils.ResponseAPIValidationError(ctx, "message body param is mandatory")
|
|
}
|
|
|
|
if err != nil || message["to"] == "" {
|
|
return routeutils.ResponseAPIValidationError(ctx, "to param is mandatory")
|
|
}
|
|
notifications := make([]viewmodel.Notification, 0)
|
|
if message["to"] == "driver" {
|
|
notifications = append(notifications, c.getDriverNotification(ride, "sms", "A message to driver", message["message"], ride.Driver.PhoneNumber, *ride.User.PhoneNumber))
|
|
} else {
|
|
notifications = append(notifications, c.getDriverNotification(ride, "sms", "A message to dispatcher", message["message"], *ride.CreatedUser.PhoneNumber, *ride.User.PhoneNumber))
|
|
notifications = append(notifications, c.getDriverNotification(ride, "email", "A message to dispatcher", message["message"], *ride.CreatedUser.Email, *ride.User.Email))
|
|
}
|
|
|
|
notifications, err = c.svc.Notification.SendNotifications(notifications)
|
|
if err != nil {
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
return routeutils.ResponseAPIOK(ctx, notifications)
|
|
}
|
|
|
|
func (c *controller) handle(ctx echo.Context) error {
|
|
var rideUUID = ctx.Param("ride_uuid")
|
|
var userUUID = ctx.Param("user_uuid")
|
|
|
|
ride, err := c.svc.Rides.GetByUUIDAndUserUUID(rideUUID, userUUID)
|
|
if err != nil {
|
|
fmt.Println("Error: ", err.Error())
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
authUser, err := c.svc.Users.GetByUUID(ride.CreatedUser.ID, "")
|
|
if err != nil {
|
|
fmt.Println("Error: ", err.Error())
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
if ride.Status.Key == "accepted" || ride.Status.Key == "pickedUp" || ride.Status.Key == "arrived" {
|
|
var lyftRide viewmodel.RideRequest
|
|
var err error
|
|
if authUser.Test {
|
|
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
|
|
} else {
|
|
lyftRide, err = c.tnc.LyftProd.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
|
|
}
|
|
if err != nil {
|
|
fmt.Println("Error: ", err.Error())
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
ride.Route.Location = ride.Route.Origin
|
|
ride.Route.Location.Address = ""
|
|
ride.Route.Location.Name = ""
|
|
|
|
switch ride.Status.Key {
|
|
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 "pickedUp":
|
|
case "arrived":
|
|
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.Latitude = lyftRide.Location.Latitude
|
|
ride.Route.Location.Longitude = lyftRide.Location.Longitude
|
|
ride.Route.Location.Bearing = lyftRide.Location.Bearing
|
|
}
|
|
}
|
|
|
|
ride.InternalID = ""
|
|
ride.User.Gender = nil
|
|
ride.User.Email = nil
|
|
ride.User.PhoneNumber = nil
|
|
ride.Passenger = viewmodel.UserLyft{}
|
|
// ride.Visit = viewmodel.Visit{
|
|
// ExternalID: ride.Visit.ExternalID,
|
|
// }
|
|
ride.CreatedUser = viewmodel.User{}
|
|
|
|
return routeutils.ResponseAPIOK(ctx, ride)
|
|
}
|
|
|
|
func (c *controller) handleReady(ctx echo.Context) error {
|
|
var rideUUID = ctx.Param("ride_uuid")
|
|
var userUUID = ctx.Param("user_uuid")
|
|
|
|
ride, err := c.svc.Rides.GetByUUIDAndUserUUID(rideUUID, userUUID)
|
|
if err != nil {
|
|
fmt.Println("Error: ", err.Error())
|
|
return routeutils.HandleAPIError(ctx, err)
|
|
}
|
|
|
|
authUser, err := c.svc.Users.GetByUUID(ride.CreatedUser.ID, "")
|
|
if err != nil {
|
|
fmt.Println("Error: ", err.Error())
|
|
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", authUser)
|
|
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 authUser.Test {
|
|
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 authUser.Test {
|
|
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, authUser)
|
|
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)
|
|
}
|