Files
old-svijetlastrana/server/router/externalroute/controller.go
2018-06-01 10:39:46 +02:00

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 = &currentTime
lyftRide.ReturnTime = &currentTime
nextRide.PickupTime = &currentTime
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)
}