package applicationservice import ( "time" "bitbucket.org/nemt/nemt-portal-api/application/entitymapping" "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" "bitbucket.org/nemt/nemt-portal-api/domain/entity" "bitbucket.org/nemt/nemt-portal-api/domain/service" "bitbucket.org/nemt/nemt-portal-api/infra/errors" ) // rideService holds methods to user application service type rideService struct { svc *service.Service mapEntity *entitymapping.Mapper } // newUserService returns a userService instance func newRideService(svc *service.Service, mapper *entitymapping.Mapper) *rideService { return &rideService{ svc: svc, mapEntity: mapper, } } func (s *rideService) UpdateNewRide(ride viewmodel.Ride, lyftRide viewmodel.RideRequest, user viewmodel.User) (viewmodel.Ride, error) { webhookModel := viewmodel.WebhookResponse{ Ride: ride, Event: lyftRide, } webhook := s.mapEntity.Ride.ToWebhookEntity(webhookModel) eUser := s.mapEntity.User.ToUserEntity(user) oldRide, err := s.svc.Rides.GetByUUID(ride.UUID, eUser) if err != nil { return viewmodel.Ride{}, err } requestMS := (oldRide.PickupTime.UnixNano() / int64(time.Millisecond)) generateDate := time.Now() generateMS := (generateDate.UnixNano() / int64(time.Millisecond)) if webhook.Ride.RequestDate == nil { webhook.Ride.RequestDate = oldRide.PickupTime } if webhook.Ride.RequestMiliseconds == nil { webhook.Ride.RequestMiliseconds = &requestMS } if webhook.Ride.GenerateDate == nil { webhook.Ride.GenerateDate = &generateDate } if webhook.Ride.GenerateMiliseconds == nil { webhook.Ride.GenerateMiliseconds = &generateMS } switch webhook.Ride.Status.Key { case "scheduled": webhook.Ride.Route.ETA = oldRide.PickupTime.UnixNano() / int64(time.Second) case "accepted": if lyftRide.Origin.ETASeconds != nil { webhook.Ride.Route.ETA = *lyftRide.Origin.ETASeconds } else { webhook.Ride.Route.ETA = 0 } case "arrived", "pickedUp": if lyftRide.Destination.ETASeconds != nil { webhook.Ride.Route.ETA = *lyftRide.Destination.ETASeconds } else { webhook.Ride.Route.ETA = 0 } case "droppedOff": webhook.Ride.Route.ETA = 0 } webhook.Ride.Route.Duration = int64(time.Now().Sub(*oldRide.PickupTime).Seconds()) webhook.Ride.InternalID = lyftRide.RideID webhook.Ride.ID = oldRide.ID webhook.Ride.UUID = oldRide.UUID webhook.Ride.Driver.ID = oldRide.Driver.ID webhook.Ride.Passenger.ID = oldRide.Passenger.ID webhook.Ride.Route.ID = oldRide.Route.ID webhook.Ride.Type.ID = oldRide.Type.ID webhook.Ride.User = oldRide.User webhook.Ride.CreatedUser = oldRide.CreatedUser webhook.Ride.Vehicle.ID = oldRide.Vehicle.ID webhook.Ride.Visit = oldRide.Visit webhook.Ride.VisitDate = oldRide.VisitDate webhook.Ride.VisitTime = oldRide.VisitTime //webhook.Ride.PickupTime = oldRide.PickupTime entityRide, err := s.svc.Rides.Update(webhook) if err != nil { return viewmodel.Ride{}, err } return s.mapEntity.Ride.ToRideModel(entityRide), nil } func (s *rideService) Update(ride viewmodel.WebhookResponse) (viewmodel.Ride, error) { webhook := s.mapEntity.Ride.ToWebhookEntity(ride) oldRide, err := s.svc.Rides.GetByInternalID(ride.Event.RideID) if err != nil { oldRide, err = s.svc.Rides.GetByInternalPassengerID(*ride.Event.Passenger.UserID) if err != nil { return viewmodel.Ride{}, err } } requestMS := (oldRide.PickupTime.UnixNano() / int64(time.Millisecond)) generateDate := time.Now() generateMS := (generateDate.UnixNano() / int64(time.Millisecond)) if webhook.Ride.RequestDate == nil { webhook.Ride.RequestDate = oldRide.PickupTime } if webhook.Ride.RequestMiliseconds == nil { webhook.Ride.RequestMiliseconds = &requestMS } if webhook.Ride.GenerateDate == nil { webhook.Ride.GenerateDate = &generateDate } if webhook.Ride.GenerateMiliseconds == nil { webhook.Ride.GenerateMiliseconds = &generateMS } switch webhook.Ride.Status.Key { case "scheduled": webhook.Ride.Route.ETA = oldRide.PickupTime.UnixNano() / int64(time.Second) case "accepted": if ride.Event.Origin.ETASeconds != nil { webhook.Ride.Route.ETA = *ride.Event.Origin.ETASeconds } else { webhook.Ride.Route.ETA = 0 } case "arrived", "pickedUp": if ride.Event.Destination.ETASeconds != nil { webhook.Ride.Route.ETA = *ride.Event.Destination.ETASeconds } else { webhook.Ride.Route.ETA = 0 } case "droppedOff": webhook.Ride.Route.ETA = 0 } webhook.Ride.Route.Duration = int64(time.Now().Sub(*oldRide.PickupTime).Seconds()) webhook.Ride.InternalID = ride.Event.RideID webhook.Ride.ID = oldRide.ID webhook.Ride.UUID = oldRide.UUID webhook.Ride.Driver.ID = oldRide.Driver.ID webhook.Ride.Passenger.ID = oldRide.Passenger.ID webhook.Ride.Route.ID = oldRide.Route.ID webhook.Ride.Type.ID = oldRide.Type.ID webhook.Ride.User = oldRide.User webhook.Ride.CreatedUser = oldRide.CreatedUser webhook.Ride.Vehicle.ID = oldRide.Vehicle.ID webhook.Ride.Visit = oldRide.Visit webhook.Ride.VisitDate = oldRide.VisitDate webhook.Ride.VisitTime = oldRide.VisitTime webhook.Ride.PickupTime = oldRide.PickupTime entityRide, err := s.svc.Rides.Update(webhook) if err != nil { return viewmodel.Ride{}, err } return s.mapEntity.Ride.ToRideModel(entityRide), nil } // Save a new ride func (s *rideService) Save(ride viewmodel.RideRequest) (viewmodel.Ride, error) { rideEntity := s.mapEntity.Ride.ToRideEntity(ride) if ride.Visit.UUID == "" { visit := entity.Visit{} visit.User = rideEntity.User visit.Pickup = rideEntity.Route.Origin visit.Notes = &rideEntity.Note visit.PickupDatetime = *rideEntity.PickupTime visit.VisitDatetime = *rideEntity.VisitTime visit.CreatedUser.UUID = ride.CreateUserUUID visit.ExternalID = ride.VisitExternalID visit.TripType = rideEntity.Visit.TripType visit.ReturnDate = ride.ReturnTime address, _ := s.svc.Users.GetAddressByUUID(rideEntity.Route.Destination.ID) createdUser, err := s.svc.Users.GetByUUID(ride.CreateUserUUID, "") if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } if address.ID > 0 { visit.DestinationAddressID = address.ID provider, err := s.svc.Provider.GetByMukID(address.InternalID, createdUser) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } visit.Provider = provider } else { provider, err := s.svc.Provider.GetByMukID(rideEntity.Route.Destination.ID, createdUser) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } visit.Provider = provider } visit, err = s.svc.Visits.Create(visit) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } rideEntity.Visit = visit } else { user, err := s.svc.Users.GetByUUID(ride.CreateUserUUID, "") if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } visit, err := s.svc.Visits.GetByUUID(ride.Visit.UUID, user) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } rideEntity.Visit = visit } retVal, err := s.svc.Rides.Save(rideEntity) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } return s.mapEntity.Ride.ToRideModel(retVal), err } // GetAll returns a list of users func (s *rideService) GetAll(user viewmodel.User) ([]viewmodel.Ride, error) { eUser := s.mapEntity.User.ToUserEntity(user) retVal, err := s.svc.Rides.GetAll(eUser) if err != nil { return nil, errors.Wrap(err) } return s.mapEntity.Ride.ToRideModelSlice(retVal), err } // GetByUUID returns a specific Ride func (s *rideService) GetByUUID(uuid string, user viewmodel.User) (viewmodel.Ride, error) { eUser := s.mapEntity.User.ToUserEntity(user) retVal, err := s.svc.Rides.GetByUUID(uuid, eUser) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } if retVal.Visit.ID > 0 { retVal.Visit, err = s.svc.Visits.GetByID(retVal.Visit.ID, eUser) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } } return s.mapEntity.Ride.ToRideModel(retVal), err } func (s *rideService) GetByVisitUUID(visitUUID string, user viewmodel.User) ([]viewmodel.Ride, error) { eUser := s.mapEntity.User.ToUserEntity(user) retVal, err := s.svc.Rides.GetByVisitUUID(visitUUID, eUser) if err != nil { return nil, errors.Wrap(err) } visit, err := s.svc.Visits.GetByUUID(visitUUID, eUser) if err != nil { return nil, errors.Wrap(err) } for i, _ := range retVal { retVal[i].Visit = visit } return s.mapEntity.Ride.ToRideModelSlice(retVal), err } func (s *rideService) GetByVisitUUIDAndTripType(visitUUID string, tripTypeKey string, user viewmodel.User) (viewmodel.Ride, error) { eUser := s.mapEntity.User.ToUserEntity(user) retVal, err := s.svc.Rides.GetByVisitUUIDAndTripType(visitUUID, tripTypeKey, eUser) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } visit, err := s.svc.Visits.GetByUUID(visitUUID, eUser) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } retVal.Visit = visit return s.mapEntity.Ride.ToRideModel(retVal), err } // GetByUUID returns a specific Ride func (s *rideService) GetByUUIDAndUserUUID(uuid string, user_uuid string) (viewmodel.Ride, error) { retVal, err := s.svc.Rides.GetByUUIDAndUserUUID(uuid, user_uuid) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } if retVal.Visit.ID > 0 { user, err := s.svc.Users.GetByID(retVal.CreatedUser.ID) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } retVal.Visit, err = s.svc.Visits.GetByID(retVal.Visit.ID, user) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } } return s.mapEntity.Ride.ToRideModel(retVal), err } // GetByInternalID returns a specific Ride func (s *rideService) GetByInternalID(internalID string) (viewmodel.Ride, error) { retVal, err := s.svc.Rides.GetByInternalID(internalID) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } if retVal.Visit.ID > 0 { user, err := s.svc.Users.GetByID(retVal.CreatedUser.ID) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } retVal.Visit, err = s.svc.Visits.GetByID(retVal.Visit.ID, user) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } } return s.mapEntity.Ride.ToRideModel(retVal), err } // GetByUserID returns a list of rides for an user func (s *rideService) GetByUserID(userID int64, user viewmodel.User) ([]viewmodel.Ride, error) { eUser := s.mapEntity.User.ToUserEntity(user) retVal, err := s.svc.Rides.GetByUserID(userID, eUser) if err != nil { return []viewmodel.Ride{}, errors.Wrap(err) } return s.mapEntity.Ride.ToRideModelSlice(retVal), err } // UpdateStatus change the status of the ride func (s *rideService) UpdateStatus(rideUUID string, status string) error { err := s.svc.Rides.UpdateStatus(rideUUID, status) if err != nil { return errors.Wrap(err) } return nil } // GetByUserID returns a list of rides for an user func (s *rideService) GetByUserUUID(userUUID string, user viewmodel.User) ([]viewmodel.Ride, error) { eUser := s.mapEntity.User.ToUserEntity(user) retVal, err := s.svc.Rides.GetByUserUUID(userUUID, eUser) if err != nil { return []viewmodel.Ride{}, errors.Wrap(err) } return s.mapEntity.Ride.ToRideModelSlice(retVal), err } func (s *rideService) GetLastRideByPhoneNumber(phoneNumber string, notificationType string, status string) (viewmodel.Ride, error) { // if notificationType == ""{ // notificationType = "message" // } if status == "" { status = "sms" } notification, err := s.svc.Notification.GetLastNotificationFromPhoneNumber(notificationType, phoneNumber, status) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } user, err := s.svc.Users.GetByID(notification.CreatedUser.ID) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } retVal, err := s.svc.Rides.GetByID(notification.Ride.ID, user) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } if retVal.Visit.ID > 0 { retVal.Visit, err = s.svc.Visits.GetByID(retVal.Visit.ID, user) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } } return s.mapEntity.Ride.ToRideModel(retVal), err } func (s *rideService) GetLastRideByDriversNumber(phoneNumber string) (viewmodel.Ride, error) { retVal, err := s.svc.Rides.GetLastRideByDriversNumber(phoneNumber) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } if retVal.Visit.ID > 0 { user, err := s.svc.Users.GetByID(retVal.CreatedUser.ID) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } retVal.Visit, err = s.svc.Visits.GetByID(retVal.Visit.ID, user) if err != nil { return viewmodel.Ride{}, errors.Wrap(err) } } return s.mapEntity.Ride.ToRideModel(retVal), err }