2 Commits

Author SHA1 Message Date
GotPPay
52656e0420 remove debugging response 2018-05-18 17:45:47 +02:00
GotPPay
c6606a98dd custom elig. api error msg ; first check elig. then create user 2018-05-18 10:46:47 +02:00
95 changed files with 591 additions and 3833 deletions

View File

@@ -1,11 +1,4 @@
FROM nginx:latest
RUN apt-get update; apt-get install -y openssl
RUN apt-get install -y ca-certificates
RUN rm -rf /etc/nginx/conf.d/*;
COPY ./dist/default.conf /etc/nginx/conf.d/
COPY ./dist/nginx.conf /etc/nginx/
FROM amazonlinux
# Sets the arguments.
ARG BIN_NAME=nemt-portal-api
@@ -14,14 +7,12 @@ ARG WORKDIR=/opt/app/
# Creates the necessary directories.
RUN mkdir -p /opt/app/docs
RUN mkdir -p /opt/app/certs
RUN mkdir -p /opt/app/static
RUN mkdir -p /var/log/bsbsi
# Copies the files to the container.
COPY ./dist/${BIN_NAME} /opt/app/${BIN_NAME}
ADD ./dist/docs/ /opt/app/docs/
ADD ./dist/certs/ /opt/app/certs/
ADD ./dist/static/ /opt/app/static/
ADD ./dist/config.toml /opt/app/config.toml
ADD ./dist/authorization_model.conf /opt/app/authorization_model.conf
@@ -29,8 +20,5 @@ ADD ./dist/authorization_policy.csv /opt/app/authorization_policy.csv
# Sets and executes the app.
WORKDIR /opt/app
EXPOSE 80
EXPOSE 443
CMD nginx & ./nemt-portal-api
EXPOSE 5000
CMD ./nemt-portal-api

View File

@@ -12,7 +12,7 @@ RUN_CONTAINER_NAME = ${APP_NAME}-run
#############################
set-loc:
$(eval DEPLOY_ENV := dev)
$(eval DEPLOY_ENV := loc)
set-dev:
$(eval DEPLOY_ENV := dev)
@@ -49,7 +49,6 @@ build: clean create-build-container
# Creates the necessary folders.
mkdir -p dist/static
mkdir -p dist/docs
mkdir -p dist/certs
# Builds inside the container.
docker run \
@@ -67,9 +66,6 @@ build: clean create-build-container
# Copies the docs and the static files to the correct folder.
cp -R static/* ./dist/static/
cp -R docs/swagger/ ./dist/docs/
cp -R certs/${DEPLOY_ENV}/ ./dist/certs/
cp default.${DEPLOY_ENV}.conf ./dist/default.conf
cp nginx.conf ./dist/nginx.conf
cp config.${DEPLOY_ENV}.toml ./dist/config.toml
cp authorization_model.conf ./dist/authorization_model.conf
cp authorization_policy.csv ./dist/authorization_policy.csv

View File

@@ -5,7 +5,6 @@ import (
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/notificationservice"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
)
@@ -17,34 +16,26 @@ var (
// Service holds the domain service repositories
type Service struct {
Users *userService
Rides *rideService
Visits *visitService
Provider *providerService
Notification *notificationService
Profile *profileService
Organization *organizationService
Zipcodes *zipcodeService
Plan *planService
PasswordReset *passwordResetService
Users *userService
Rides *rideService
Visits *visitService
Provider *providerService
Notification *notificationService
Profile *profileService
Organization *organizationService
}
// New returns a new domain Service instance
func New(svc *service.Service, mapper *entitymapping.Mapper, notification *notificationservice.Service, cfg *config.Config) *Service {
once.Do(func() {
bcbsi := bcbsi.New(cfg)
instance = &Service{
Users: newUserService(svc, mapper),
Rides: newRideService(svc, mapper),
Visits: newVisitService(svc, mapper),
Provider: newProviderService(svc, mapper),
Notification: newNotificationService(svc, mapper, notification, cfg),
Profile: newProfileService(svc, mapper),
Organization: newOrganizationService(svc, mapper),
Zipcodes: newZipcodeService(svc, mapper),
Plan: newPlanService(svc, mapper),
PasswordReset: newPasswordResetService(svc, mapper),
Users: newUserService(svc, mapper),
Rides: newRideService(svc, mapper),
Visits: newVisitService(svc, mapper),
Provider: newProviderService(svc, mapper),
Notification: newNotificationService(svc, mapper, notification, cfg),
Profile: newProfileService(svc, mapper),
Organization: newOrganizationService(svc, mapper),
}
})

View File

@@ -550,56 +550,6 @@ func (s *notificationService) ReadStatus(notificationUUID string, isRead bool) e
return s.svc.Notification.ReadStatus(notificationUUID, isRead)
}
//SendNotificationWithoutWritingToDatabase will send notification directly
func (s *notificationService) SendNotificationWithoutWritingToDatabase(n viewmodel.Notification) (viewmodel.Notification, error) {
switch n.Type {
case NOtificationTypeSMS:
if n.From == "" {
if err := s.notification.Twilio.SendSMS(s.cfg.Twilio.Sender, n.To, n.Message); err != nil {
fmt.Println("Error to send SMS: ", err.Error())
return viewmodel.Notification{}, err
}
if err := s.notification.Twilio.SendSMS(s.cfg.Twilio.Sender, "+17083038497", n.Message); err != nil {
fmt.Println("Error to send SMS: ", err.Error())
return viewmodel.Notification{}, err
}
} else {
if err := s.notification.Twilio.SendSMS(n.From, n.To, n.Message); err != nil {
fmt.Println("Error to send SMS: ", err.Error())
return viewmodel.Notification{}, err
}
if err := s.notification.Twilio.SendSMS(n.From, "+17083038497", n.Message); err != nil {
fmt.Println("Error to send SMS: ", err.Error())
return viewmodel.Notification{}, err
}
}
case NotificationTypeEmail:
m := gomail.NewMessage()
m.SetHeader("From", s.cfg.Email.Sender)
m.SetHeader("To", n.To)
m.SetHeader("Subject", n.Subject)
m.SetBody("text/plain", n.Message)
d := gomail.NewDialer(s.cfg.Email.Server, s.cfg.Email.Port, s.cfg.Email.User, s.cfg.Email.Pass)
if err := d.DialAndSend(m); err != nil {
fmt.Println("Error to send Email: ", err.Error())
return viewmodel.Notification{}, err
}
m = gomail.NewMessage()
m.SetHeader("From", s.cfg.Email.Sender)
m.SetHeader("To", "nemt@brighterdevelopment.com")
m.SetHeader("Subject", n.Subject)
m.SetBody("text/plain", n.Message)
if err := d.DialAndSend(m); err != nil {
fmt.Println("Error to send Email: ", err.Error())
return viewmodel.Notification{}, err
}
}
return n, nil
}
// SendNotifications will send all the notifications to email or SMS
func (s *notificationService) SendNotifications(notifications []viewmodel.Notification) ([]viewmodel.Notification, error) {
if len(notifications) > 0 {

View File

@@ -48,16 +48,6 @@ func (s *organizationService) GetByType(organizationTypeKey string, user viewmod
func (s *organizationService) GetByUUID(organizationUUID string, user viewmodel.User) (viewmodel.Organization, error) {
userEntity := s.mapEntity.User.ToUserEntity(user)
result, err := s.svc.Organization.GetByUUID(organizationUUID, userEntity)
if err != nil {
fmt.Println("Error to get the Organization data by UUID", err)
return viewmodel.Organization{}, err
}
return s.mapEntity.Organization.ToOrganizationModel(result), nil
}
func (s *organizationService) GetByTypeAndReferenceID(typeKey string, referenceID int64, user viewmodel.User) (viewmodel.Organization, error) {
userEntity := s.mapEntity.User.ToUserEntity(user)
result, err := s.svc.Organization.GetByTypeAndReferenceID(typeKey, referenceID, userEntity)
if err != nil {
return viewmodel.Organization{}, err
}
@@ -195,17 +185,17 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio
var provider npdmodel.ProviderResponse
bProvider, err := ffjson.Marshal(organization.Reference)
if err != nil {
fmt.Println("Error to marshal provider", err)
fmt.Println("Error to marshal provider")
return viewmodel.Organization{}, nil
}
if err := ffjson.Unmarshal(bProvider, &provider); err != nil {
fmt.Println("Error to convert provider", err)
fmt.Println("Error to convert provider")
return viewmodel.Organization{}, nil
}
eProviders, err := s.svc.Provider.Save(s.mapEntity.Provider.ToProviderEntitySlice([]npdmodel.ProviderResponse{provider}), enUser)
if err != nil {
fmt.Println("Error to save provider", err)
fmt.Println("Error to save provider")
return viewmodel.Organization{}, nil
}
respProvider := eProviders[0]
@@ -213,19 +203,17 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio
lat, _ := strconv.ParseFloat(provider.Latitude, 64)
long, _ := strconv.ParseFloat(provider.Longitude, 64)
if lat != 0 && long != 0 && len(provider.StreetName1) > 0 {
address := entity.OrganizationAddress{
InternalID: provider.MukID,
Name: "Main Address",
Address: fmt.Sprintf("%s %s - %s, %s (%s)", provider.StreetName1, provider.StreetName2, provider.CityName, provider.State, provider.ZipCode[:5]),
Latitude: lat,
Longitude: long,
CreatedUser: enOrg.Author,
UpdatedUser: enOrg.LastEditor,
}
enOrg.Addresses = append(enOrg.Addresses, address)
address := entity.OrganizationAddress{
InternalID: provider.MukID,
Name: "Main Address",
Address: fmt.Sprintf("%s %s - %s, %s (%s)", provider.StreetName1, provider.StreetName2, provider.CityName, provider.State, provider.ZipCode),
Latitude: lat,
Longitude: long,
CreatedUser: enOrg.Author,
UpdatedUser: enOrg.LastEditor,
}
enOrg.Addresses = append(enOrg.Addresses, address)
fmt.Println("Phone Number: ", provider.PhoneNumber)
if provider.PhoneNumber != "" {
formattedPhone := "+1" + strings.Replace(provider.PhoneNumber, "-", "", -1)
contact := entity.OrganizationContact{
@@ -244,9 +232,8 @@ func (s *organizationService) AddOrganization(organization viewmodel.Organizatio
enOrg, err = s.svc.Organization.AddOrganization(enOrg, enUser)
if err != nil {
fmt.Println("Error to save organization on DB", err)
return viewmodel.Organization{}, nil
}
return s.mapEntity.Organization.ToOrganizationModel(enOrg), nil
return s.GetByUUID(enOrg.UUID, user)
}

View File

@@ -1,62 +0,0 @@
package applicationservice
import (
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
)
// zipcodeService holds methods to participating zipcode application service
type passwordResetService struct {
svc *service.Service
mapEntity *entitymapping.Mapper
}
// newZipcodeService returns a zipcodeService instance
func newPasswordResetService(svc *service.Service, mapper *entitymapping.Mapper) *passwordResetService {
return &passwordResetService{
svc: svc,
mapEntity: mapper,
}
}
func (s *passwordResetService) GetAll() ([]viewmodel.PasswordReset, error) {
result, err := s.svc.PasswordReset.GetAll()
if err != nil {
return nil, err
}
return s.mapEntity.PasswordReset.ToPasswordResetModelSlice(result), nil
}
func (s *passwordResetService) CreatePasswordResetEntry(passwordResetEntry viewmodel.PasswordReset) (viewmodel.PasswordReset, error) {
passwordResetEntity := s.mapEntity.PasswordReset.ToPasswordResetEntity(passwordResetEntry)
result, err := s.svc.PasswordReset.CreatePasswordResetEntry(passwordResetEntity)
if err != nil {
return viewmodel.PasswordReset{}, err
}
return s.mapEntity.PasswordReset.ToPasswordResetModel(result), nil
}
func (s *passwordResetService) GetByID(ID int64) (viewmodel.PasswordReset, error) {
result, err := s.svc.PasswordReset.GetByID(ID)
if err != nil {
return viewmodel.PasswordReset{}, err
}
return s.mapEntity.PasswordReset.ToPasswordResetModel(result), nil
}
func (s *passwordResetService) GetByToken(token string) (viewmodel.PasswordReset, error) {
result, err := s.svc.PasswordReset.GetByToken(token)
if err != nil {
return viewmodel.PasswordReset{}, err
}
return s.mapEntity.PasswordReset.ToPasswordResetModel(result), nil
}
func (s *passwordResetService) SetTokenOpened(token string) error {
return s.svc.PasswordReset.SetTokenOpened(token)
}
func (s *passwordResetService) SetTokenUsed(token string) error {
return s.svc.PasswordReset.SetTokenUsed(token)
}

View File

@@ -1,57 +0,0 @@
package applicationservice
import (
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
)
// providerService holds methods to provider application service
type planService struct {
svc *service.Service
mapEntity *entitymapping.Mapper
}
// newProviderService returns a providerService instance
func newPlanService(svc *service.Service, mapper *entitymapping.Mapper) *planService {
return &planService{
svc: svc,
mapEntity: mapper,
}
}
func (s *planService) GetByAlphaPrefix(alphaPrefix string) (viewmodel.Plan, error) {
plan, err := s.svc.Plans.GetByAlphaPrefix(alphaPrefix)
if err != nil {
return viewmodel.Plan{}, err
}
return s.mapEntity.Plan.ToPlanModel(plan), nil
}
func (s *planService) GetByUUID(planUUID string) ([]viewmodel.Plan, error) {
plans, err := s.svc.Plans.GetByUUID(planUUID)
if err != nil {
return nil, err
}
return s.mapEntity.Plan.ToPlanModelSlice(plans), nil
}
func (s *planService) GetByID(planID int64) ([]viewmodel.Plan, error) {
plans, err := s.svc.Plans.GetByID(planID)
if err != nil {
return nil, err
}
return s.mapEntity.Plan.ToPlanModelSlice(plans), nil
}
func (s *planService) GetByPrefixUUID(prefixUUID string) (viewmodel.Plan, error) {
plan, err := s.svc.Plans.GetByPrefixUUID(prefixUUID)
if err != nil {
return viewmodel.Plan{}, err
}
return s.mapEntity.Plan.ToPlanModel(plan), nil
}

View File

@@ -48,33 +48,3 @@ func (s *providerService) Get(query string, lat float64, long float64, distance
}
return s.mapEntity.Provider.ToProviderRespModelSlice(providers), nil
}
func (s *providerService) GetByUUID(providerUUID string, user viewmodel.User) (viewmodel.ProviderResp, error) {
eUser := s.mapEntity.User.ToUserEntity(user)
provider, err := s.svc.Provider.GetByUUID(providerUUID, eUser)
if err != nil {
return viewmodel.ProviderResp{}, err
}
return s.mapEntity.Provider.ToProviderRespModel(provider), nil
}
func (s *providerService) GetByNPI(NPI string, user viewmodel.User) (viewmodel.ProviderResp, error) {
eUser := s.mapEntity.User.ToUserEntity(user)
provider, err := s.svc.Provider.GetByNPI(NPI, eUser)
if err != nil {
return viewmodel.ProviderResp{}, err
}
return s.mapEntity.Provider.ToProviderRespModel(provider), nil
}
func (s *providerService) GetByOrganization(organizationUUID string, user viewmodel.User) (viewmodel.ProviderResp, error) {
eUser := s.mapEntity.User.ToUserEntity(user)
provider, err := s.svc.Provider.GetByOrganization(organizationUUID, eUser)
if err != nil {
return viewmodel.ProviderResp{}, err
}
return s.mapEntity.Provider.ToProviderRespModel(provider), nil
}

View File

@@ -1,7 +1,6 @@
package applicationservice
import (
"fmt"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
@@ -184,7 +183,6 @@ func (s *rideService) Save(ride viewmodel.RideRequest) (viewmodel.Ride, error) {
address, _ := s.svc.Users.GetAddressByUUID(rideEntity.Route.Destination.ID)
createdUser, err := s.svc.Users.GetByUUID(ride.CreateUserUUID, "")
if err != nil {
fmt.Println("Ride Application.Save: Error to get User: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}
@@ -192,14 +190,12 @@ func (s *rideService) Save(ride viewmodel.RideRequest) (viewmodel.Ride, error) {
visit.DestinationAddressID = address.ID
provider, err := s.svc.Provider.GetByMukID(address.InternalID, createdUser)
if err != nil {
fmt.Println("Ride Application.Save: Error to get Provider: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}
visit.Provider = provider
} else {
provider, err := s.svc.Provider.GetByMukID(rideEntity.Route.Destination.ID, createdUser)
if err != nil {
fmt.Println("Ride Application.Save: Error to get Provider by Route: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}
visit.Provider = provider
@@ -207,20 +203,17 @@ func (s *rideService) Save(ride viewmodel.RideRequest) (viewmodel.Ride, error) {
visit, err = s.svc.Visits.Create(visit)
if err != nil {
fmt.Println("Ride Application.Save: Error creating visit: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}
rideEntity.Visit = visit
} else {
user, err := s.svc.Users.GetByUUID(ride.CreateUserUUID, "")
if err != nil {
fmt.Println("Ride Application.Save: Error getting User: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}
visit, err := s.svc.Visits.GetByUUID(ride.Visit.UUID, user)
if err != nil {
fmt.Println("Ride Application.Save: Error getting Visit: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}
rideEntity.Visit = visit
@@ -228,7 +221,6 @@ func (s *rideService) Save(ride viewmodel.RideRequest) (viewmodel.Ride, error) {
retVal, err := s.svc.Rides.Save(rideEntity)
if err != nil {
fmt.Println("Ride Application.Save: Error saving ride: ", err.Error())
return viewmodel.Ride{}, errors.Wrap(err)
}

View File

@@ -1,40 +1,24 @@
package applicationservice
import (
"context"
"encoding/xml"
"fmt"
"html"
"math/rand"
"strings"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
"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/config"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
"bitbucket.org/nemt/nemt-portal-api/server/validation"
"googlemaps.github.io/maps"
)
// userService holds methods to user application service
type userService struct {
svc *service.Service
mapEntity *entitymapping.Mapper
bcbsi *bcbsi.Service
cfg *config.Config
}
// newUserService returns a userService instance
func newUserService(svc *service.Service, mapper *entitymapping.Mapper, bcbsi *bcbsi.Service, cfg *config.Config) *userService {
func newUserService(svc *service.Service, mapper *entitymapping.Mapper) *userService {
return &userService{
svc: svc,
mapEntity: mapper,
bcbsi: bcbsi,
cfg: cfg,
}
}
@@ -67,26 +51,6 @@ func (s *userService) GetByUUID(uuid string, profile string) (retVal viewmodel.U
return s.mapEntity.User.ToUserModel(user), nil
}
// GetByID returns a specific user by its ID
func (s *userService) GetByMemberID(memberID string) (retVal viewmodel.User, err error) {
user, err := s.svc.Users.GetByMemberID(memberID)
if err != nil {
return retVal, errors.Wrap(err)
}
return s.mapEntity.User.ToUserModel(user), nil
}
// GetByEmail returns a specific user by its email
func (s *userService) GetByEmail(email string) (retVal viewmodel.User, err error) {
user, err := s.svc.Users.GetByEmail(email)
if err != nil {
return retVal, errors.Wrap(err)
}
return s.mapEntity.User.ToUserModel(user), nil
}
// Login returns a specific user by email and pass
func (s *userService) FullLogin(loginType string, key string, pass string, profile string) (retVal viewmodel.User, err error) {
user, err := s.svc.Users.FullLogin(loginType, key, pass, profile)
@@ -167,11 +131,6 @@ func (s *userService) RemoveAddress(addressUUID string) error {
return s.svc.Users.RemoveAddress(addressUUID)
}
func (s *userService) UpdateLogin(user viewmodel.User) error {
eUser := s.mapEntity.User.ToUserEntity(user)
return s.svc.Users.UpdateLogin(eUser)
}
func (s *userService) SaveAddress(address viewmodel.Address) (retVal viewmodel.Address, err error) {
entity := s.mapEntity.Address.ToAddressEntity(address)
entity, err = s.svc.Users.SaveAddress(entity)
@@ -210,215 +169,3 @@ func (s *userService) RemoveContact(contact viewmodel.Contact) (retVal viewmodel
return s.mapEntity.User.ToContactModel(entity), err
}
func (s *userService) rangeIn(low, hi int) string {
result := low + rand.Intn(hi-low)
return fmt.Sprintf("%v", result)
}
func (s *userService) generatePassword(n int) string {
const (
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
return s.stringWithCharset(n, charset)
}
func (s *userService) stringWithCharset(length int, charset string) string {
b := make([]byte, length)
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}
func (s *userService) CheckAndCreateMember(user viewmodel.User, provider viewmodel.ProviderResp, authorUser viewmodel.User) (viewmodel.User, error) {
if validationErrors := validation.ValidateEligibility(&user); len(validationErrors) > 0 {
return viewmodel.User{}, &viewmodel.ValidationError{Message: "Eligibility validation failed", Errors: validationErrors}
}
entityUser := s.mapEntity.User.ToUserEntity(user)
entityAuthorUser := s.mapEntity.User.ToUserEntity(authorUser)
entityProvider := s.mapEntity.Provider.ToProviderRespEntity(provider)
newEmail := entityUser.Email
newPhoneNumber := entityUser.PhoneNumber
var err error
if entityUser.UUID != "" {
entityUser, err = s.svc.Users.GetByUUID(entityUser.UUID, "US")
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error finding user by UUID: %s", err.Error())}
}
} else {
entityUser, err = s.svc.Users.GetByMemberID(entityUser.Member)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error finding user by Subscriber ID: %s", err.Error())}
}
}
var eligibility viewmodel.Eligibility
loc, _ := time.LoadLocation("America/Chicago")
eligibility.TrackingID = s.rangeIn(1000000, 9999999)
eligibility.ServiceInfo.DateOfService = time.Now().In(loc)
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
if entityProvider.InternalID == "" && entityProvider.ProviderUUID != "" {
entityProvider, err = s.svc.Provider.GetByUUID(entityProvider.ProviderUUID, entityAuthorUser)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error finding provider by UUID: %s", err.Error())}
}
} else {
entityProvider, err = s.svc.Provider.GetByNPI(entityProvider.InternalID, entityAuthorUser)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error finding provider by NPI: %s", err.Error())}
}
}
if entityProvider.InternalID == "" {
return viewmodel.User{}, &viewmodel.ValidationError{Message: "Provider not found"}
} else {
eligibility.Provider.ProviderNPI = entityProvider.InternalID
eligibility.Provider.ProviderName = entityProvider.OrganizatioName
}
plan, err := s.svc.Plans.GetByAlphaPrefix(entityUser.Member[:3])
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error finding Plan: %s", err.Error())}
}
eligibility.Payer.PayerID = fmt.Sprintf("%v", plan.PayerID)
eligibility.Payer.PayerName = plan.PayerName
eligibility.Subscriber.SubscriberID = entityUser.Member
eligibility.Subscriber.PatientType = entityUser.Type
eligibility.Subscriber.Name.First = strings.Split(entityUser.Name, " ")[0]
eligibility.Subscriber.Name.Last = strings.Split(entityUser.Name, " ")[1]
eligibility.Subscriber.DemographicInfo.DateOfBirth = entityUser.BirthDate
eligibility.Subscriber.DemographicInfo.Gender = entityUser.Gender
ret, err := s.bcbsi.BXE.CheckEligibility(eligibility)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error checking eligibility: %s", err.Error())}
}
if ret.QueryResult.QueryResultSummary.BenefitsFound {
xmlString := html.UnescapeString(ret.QueryResult.HIPPA271.T271)
xmlReader := strings.NewReader(xmlString)
var f viewmodel.Interchange271
err = xml.NewDecoder(xmlReader).Decode(&f)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error unmarshaling 271 response: %s", err.Error())}
}
header := f.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N3_0950
body := f.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N4_0960
zipCode := strings.TrimSpace(body.N403)
if len(strings.TrimSpace(zipCode)) > 5 {
zipCode = strings.TrimSpace(zipCode)[:5]
}
if !s.cfg.App.DisableZipValidation {
_, err = s.svc.Zipcodes.GetByParticipatingZipcode(zipCode)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Member's Home zipcode, %s, is not currently eligible for participation in this program", zipCode)}
}
}
if entityUser.ID == 0 {
profile, err := s.svc.Profile.GetByKey("US")
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error getting user profile: %s", err.Error())}
}
entityUser.Profiles = append(entityUser.Profiles, profile)
if len(entityUser.PhoneNumber) == 10 && !strings.Contains(entityUser.PhoneNumber, "+1") {
phoneNumber := fmt.Sprintf("+1%s", entityUser.PhoneNumber)
entityUser.PhoneNumber = phoneNumber
}
entityUser.Test = false
entityUser, err = s.svc.Users.Create(entityUser)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error creating user: %s", err.Error())}
}
} else {
if len(newEmail) > 0 && newEmail != entityUser.Email {
entityUser.Email = newEmail
}
if len(newPhoneNumber) > 0 && len(newPhoneNumber) == 10 && !strings.Contains(newPhoneNumber, "+1") {
newPhoneNumber = fmt.Sprintf("+1%s", newPhoneNumber)
}
if len(newPhoneNumber) > 0 && len(newPhoneNumber) == 12 && strings.Contains(newPhoneNumber, "+1") {
entityUser.PhoneNumber = newPhoneNumber
}
err = s.svc.Users.UpdateLogin(entityUser)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error updating login data: %s", err.Error())}
}
}
address := entity.Address{}
address.AddressType = entity.Params{
Key: "home",
Name: "Home",
}
address.Name = fmt.Sprintf("%s, %s", header.N301, body.N401)
address.Address = fmt.Sprintf("%s, %s (%s)", header.N301, body.N401, zipCode)
address.CreatedUser = entityAuthorUser
address.User = entityUser
address.Origin = entity.Params{
Key: "provider",
Name: "Provider",
}
googleMapsAPI, err := maps.NewClient(maps.WithClientIDAndSignature("gme-bluecrossandblue1", "msqgD-jdqCyR0M_1u5C1HION5iI="))
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error instanciating google maps: %s", err.Error())}
}
r := &maps.GeocodingRequest{
Address: address.Address + " " + body.N402 + ", " + zipCode,
}
result, err := googleMapsAPI.Geocode(context.Background(), r)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error getting geocode info: %s", err.Error())}
}
if len(result) > 0 {
address.Latitude = result[0].Geometry.Location.Lat
address.Longitude = result[0].Geometry.Location.Lng
}
if len(user.Addresses) > 0 {
for _, a := range user.Addresses {
if a.AddressType == "home" {
err := s.svc.Users.RemoveAddress(a.UUID)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error removing old address: %s", err.Error())}
}
}
}
}
address, err = s.svc.Users.SaveAddress(address)
if err != nil {
return viewmodel.User{}, &viewmodel.ValidationError{Message: fmt.Sprintf("Error saving new address: %s", err.Error())}
}
entityUser.Addresses = append(entityUser.Addresses, address)
return s.mapEntity.User.ToUserModel(entityUser), nil
} else {
return viewmodel.User{}, &viewmodel.ValidationError{Message: "No benefits found for the member"}
}
return viewmodel.User{}, nil
}

View File

@@ -1,8 +1,6 @@
package applicationservice
import (
"fmt"
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
@@ -23,43 +21,6 @@ func newVisitService(svc *service.Service, mapper *entitymapping.Mapper) *visitS
}
}
func (s *visitService) Save(visit viewmodel.Visit) (viewmodel.Visit, error) {
entity := s.mapEntity.Visit.ToVisitEntity(visit)
for _, a := range visit.User.Addresses {
if a.AddressType == "home" {
address, err := s.svc.Users.GetAddressByUUID(a.UUID)
if err != nil {
fmt.Println("Application Visit: Address UUID: ", a.UUID)
fmt.Println("Application Visit: Address Error: ", err.Error())
return viewmodel.Visit{}, err
}
entity.PickupAddressID = address.ID
entity.Pickup.Address = address.Address
entity.Pickup.ID = address.UUID
entity.Pickup.Latitude = address.Latitude
entity.Pickup.Longitude = address.Longitude
entity.Pickup.Name = address.Name
}
}
provider, err := s.svc.Provider.GetByUUID(entity.Provider.ProviderUUID, entity.CreatedUser)
if err != nil {
fmt.Println("Application Visit: Provider UUID: ", entity.Provider.ProviderUUID)
fmt.Println("Application Visit: Provider Error: ", err.Error())
return viewmodel.Visit{}, errors.Wrap(err)
}
entity.Provider = provider
retVal, err := s.svc.Visits.Create(entity)
if err != nil {
fmt.Println("Application Visit: Create Visit Error: ", err.Error())
return viewmodel.Visit{}, errors.Wrap(err)
}
return s.mapEntity.Visit.ToVisitModel(retVal), err
}
// Save a new ride
func (s *visitService) Create(visit viewmodel.Visit) (viewmodel.Visit, error) {
entity := s.mapEntity.Visit.ToVisitEntity(visit)
@@ -87,23 +48,8 @@ func (s *visitService) GetByUUID(visitUUID string, user viewmodel.User) (viewmod
eUser := s.mapEntity.User.ToUserEntity(user)
retVal, err := s.svc.Visits.GetByUUID(visitUUID, eUser)
if err != nil {
fmt.Println("Visit Application: Error getting visit: ", err.Error())
return viewmodel.Visit{}, errors.Wrap(err)
}
visitUser, err := s.svc.Users.GetByUUID(retVal.User.UUID, "US")
if err != nil {
fmt.Println("Visit Application: Error getting user: ", err.Error())
return viewmodel.Visit{}, errors.Wrap(err)
}
retVal.User = visitUser
provider, err := s.svc.Provider.GetByUUID(retVal.Provider.ProviderUUID, eUser)
if err != nil {
fmt.Println("Visit Application: Error getting provider: ", err.Error())
return viewmodel.Visit{}, errors.Wrap(err)
}
retVal.Provider = provider
return s.mapEntity.Visit.ToVisitModel(retVal), err
}

View File

@@ -1,37 +0,0 @@
package applicationservice
import (
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
)
// zipcodeService holds methods to participating zipcode application service
type zipcodeService struct {
svc *service.Service
mapEntity *entitymapping.Mapper
}
// newZipcodeService returns a zipcodeService instance
func newZipcodeService(svc *service.Service, mapper *entitymapping.Mapper) *zipcodeService {
return &zipcodeService{
svc: svc,
mapEntity: mapper,
}
}
func (s *zipcodeService) GetAll() ([]viewmodel.Zipcode, error) {
result, err := s.svc.Zipcodes.GetAll()
if err != nil {
return nil, err
}
return s.mapEntity.Zipcode.ToZipcodeModelSlice(result), nil
}
func (s *zipcodeService) GetByParticipatingZipcode(zipcode string) (viewmodel.Zipcode, error) {
result, err := s.svc.Zipcodes.GetByParticipatingZipcode(zipcode)
if err != nil {
return viewmodel.Zipcode{}, err
}
return s.mapEntity.Zipcode.ToZipcodeModel(result), nil
}

View File

@@ -13,17 +13,14 @@ var (
// Mapper has mapping methods to map entities to view models
type Mapper struct {
User *userMapping
Ride *rideMapping
Visit *visitMapping
Address *addressMapping
Provider *providerMapping
Notification *notificationMapping
Profile *profileMapping
Organization *organizationMapping
Zipcode *zipcodeMapping
Plan *planMapping
PasswordReset *passwordResetMapping
User *userMapping
Ride *rideMapping
Visit *visitMapping
Address *addressMapping
Provider *providerMapping
Notification *notificationMapping
Profile *profileMapping
Organization *organizationMapping
}
// New returns an EntityMapper for fluent mapping
@@ -39,9 +36,6 @@ func New() *Mapper {
instance.Notification = &notificationMapping{instance}
instance.Profile = &profileMapping{instance}
instance.Organization = &organizationMapping{instance}
instance.Zipcode = &zipcodeMapping{instance}
instance.Plan = &planMapping{instance}
instance.PasswordReset = &passwordResetMapping{instance}
})
return instance

View File

@@ -1,59 +0,0 @@
package entitymapping
import (
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
// zipcodeMapping has method to map zipcode entities to view models
type passwordResetMapping struct {
mapper *Mapper
}
// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *passwordResetMapping) ToPasswordResetEntitySlice(list []viewmodel.PasswordReset) (retVal []entity.PasswordReset) {
retVal = make([]entity.PasswordReset, 0)
for _, item := range list {
retVal = append(retVal, mapping.ToPasswordResetEntity(item))
}
return retVal
}
func (mapping *passwordResetMapping) ToPasswordResetEntity(model viewmodel.PasswordReset) entity.PasswordReset {
return entity.PasswordReset{
ID: model.ID,
UUID: model.UUID,
User: mapping.mapper.User.ToUserEntity(model.User),
Token: model.Token,
Created: model.Created,
Expires: model.Expires,
Used: model.Used,
Opened: model.Opened,
}
}
// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *passwordResetMapping) ToPasswordResetModelSlice(list []entity.PasswordReset) (retVal []viewmodel.PasswordReset) {
retVal = make([]viewmodel.PasswordReset, 0)
for _, item := range list {
retVal = append(retVal, mapping.ToPasswordResetModel(item))
}
return retVal
}
func (mapping *passwordResetMapping) ToPasswordResetModel(model entity.PasswordReset) viewmodel.PasswordReset {
return viewmodel.PasswordReset{
ID: model.ID,
UUID: model.UUID,
User: mapping.mapper.User.ToUserModel(model.User),
Token: model.Token,
Created: model.Created,
Expires: model.Expires,
Used: model.Used,
Opened: model.Opened,
}
}

View File

@@ -1,65 +0,0 @@
package entitymapping
import (
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
// providerMapping has method to map provider entities to view models
type planMapping struct {
mapper *Mapper
}
// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *planMapping) ToPlanEntitySlice(list []viewmodel.Plan) (retVal []entity.Plan) {
retVal = make([]entity.Plan, 0)
for _, item := range list {
retVal = append(retVal, mapping.ToPlanEntity(item))
}
return retVal
}
func (mapping *planMapping) ToPlanEntity(model viewmodel.Plan) entity.Plan {
return entity.Plan{
UUID: model.ID,
Name: model.Name,
InternalID: model.InternalID,
Status: model.Status,
PlanEntityID: model.PlanEntityID,
EntityID: model.EntityID,
PayerID: model.PayerID,
PayerName: model.PayerName,
PrefixUUID: model.PrefixID,
AlphaPrefix: model.AlphaPrefix,
Active: model.Active,
}
}
// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *planMapping) ToPlanModelSlice(list []entity.Plan) (retVal []viewmodel.Plan) {
retVal = make([]viewmodel.Plan, 0)
for _, item := range list {
retVal = append(retVal, mapping.ToPlanModel(item))
}
return retVal
}
func (mapping *planMapping) ToPlanModel(model entity.Plan) viewmodel.Plan {
return viewmodel.Plan{
ID: model.UUID,
Name: model.Name,
InternalID: model.InternalID,
Status: model.Status,
PlanEntityID: model.PlanEntityID,
EntityID: model.EntityID,
PayerID: model.PayerID,
PayerName: model.PayerName,
PrefixID: model.PrefixUUID,
AlphaPrefix: model.AlphaPrefix,
Active: model.Active,
}
}

View File

@@ -37,7 +37,6 @@ func (mapping *providerMapping) ToProviderRespEntity(item viewmodel.ProviderResp
LastName: item.LastName,
Title: item.Title,
Distance: item.Distance,
Organization: mapping.mapper.Organization.ToOrganizationEntity(item.Organization),
}
}
@@ -69,7 +68,6 @@ func (mapping *providerMapping) ToProviderRespModel(item entity.Provider) viewmo
Keys: mapping.ToProviderKeyModelSlice(item.Keys),
Address: mapping.ToProviderRespAddressModel(item.Address),
Distance: item.Distance,
Organization: mapping.mapper.Organization.ToOrganizationModel(item.Organization),
}
}

View File

@@ -50,8 +50,6 @@ func (mapping *userMapping) ToUserModel(item entity.User) viewmodel.User {
Profiles: mapping.mapper.Profile.ToProfileModelSlice(item.Profiles),
Organizations: mapping.mapper.Organization.ToOrganizationModelSlice(item.Organizations),
Types: mapping.mapper.Organization.ToOrganizationTypeModelSlice(item.Types),
Type: &item.Type,
Test: item.Test,
}
}
@@ -79,13 +77,6 @@ func (mapping *userMapping) ToUserEntity(item viewmodel.User) entity.User {
Profiles: mapping.mapper.Profile.ToProfileEntitySlice(item.Profiles),
Organizations: mapping.mapper.Organization.ToOrganizationEntitySlice(item.Organizations),
Types: mapping.mapper.Organization.ToOrganizationTypeEntitySlice(item.Types),
Test: item.Test,
}
if item.Type == nil {
user.Type = "S"
} else {
user.Type = *item.Type
}
if user.Name == "" {

View File

@@ -1,51 +0,0 @@
package entitymapping
import (
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
// zipcodeMapping has method to map zipcode entities to view models
type zipcodeMapping struct {
mapper *Mapper
}
// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *zipcodeMapping) ToZipcodeEntitySlice(list []viewmodel.Zipcode) (retVal []entity.Zipcode) {
retVal = make([]entity.Zipcode, 0)
for _, item := range list {
retVal = append(retVal, mapping.ToZipcodeEntity(item))
}
return retVal
}
func (mapping *zipcodeMapping) ToZipcodeEntity(model viewmodel.Zipcode) entity.Zipcode {
return entity.Zipcode{
ID: model.ID,
UUID: model.UUID,
Zipcode: model.Zipcode,
Participating: model.Participating,
}
}
// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *zipcodeMapping) ToZipcodeModelSlice(list []entity.Zipcode) (retVal []viewmodel.Zipcode) {
retVal = make([]viewmodel.Zipcode, 0)
for _, item := range list {
retVal = append(retVal, mapping.ToZipcodeModel(item))
}
return retVal
}
func (mapping *zipcodeMapping) ToZipcodeModel(model entity.Zipcode) viewmodel.Zipcode {
return viewmodel.Zipcode{
ID: model.ID,
UUID: model.UUID,
Zipcode: model.Zipcode,
Participating: model.Participating,
}
}

View File

@@ -98,10 +98,13 @@ func (s bxeService) Get271(eligibility viewmodel.Eligibility) (bcbsimodel.Interc
}
func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimodel.MemberEligibilityResponse, error) {
if eligibility.Payer.PayerID == "" || eligibility.Payer.PayerName == "" {
eligibility.Payer.PayerID = "621"
eligibility.Payer.PayerName = "blue_cross_blue_shield_il"
}
// payer, err := s.GetPayerDetails(eligibility.Subscriber.SubscriberID)
// if err != nil {
// return bcbsimodel.MemberEligibilityResponse{}, err
// }
eligibility.Payer.PayerID = "621"
eligibility.Payer.PayerName = "blue_cross_blue_shield_il"
envelope := bcbsimodel.GetEnvelope(eligibility)
apiKey := s.cfg.BXE.APIKey
@@ -119,14 +122,11 @@ func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimo
req.Header.Add("X-Api-Key", apiKey)
req.Header.Add("X-Signature", s.getSignature(apiKey, secretKey))
eligibilityCall := time.Now()
fmt.Println(fmt.Sprintf("Start eligibility call %s at %s", eligibility.TrackingID, eligibilityCall.Format("2006-01-02 15:04:05 PM")))
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error WebService Request: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
fmt.Println(fmt.Sprintf("Getting Response from eligibility call %s at %s, duration %f seconds", eligibility.TrackingID, time.Now().Format("2006-01-02 15:04:05 PM"), time.Since(eligibilityCall).Seconds()))
defer resp.Body.Close()
bReturn, err := ioutil.ReadAll(resp.Body)

View File

@@ -262,7 +262,6 @@ func (s *lyftService) RequestRide(rideRequest viewmodel.RideRequest) (viewmodel.
if raw.Error != "" {
fmt.Println("Error to call Lyft: ", raw.Error+" - "+raw.ErrorDescription)
fmt.Println("Full body error: ", string(body))
return viewmodel.RideRequest{}, errors.New("Lyft Error: " + raw.Error + " - " + raw.ErrorDescription)
}

View File

@@ -6,13 +6,11 @@ import (
)
type Eligibility struct {
TrackingID string `json:"tracking_id,omitempty"`
Payer Payer `json:"payer,omitempty"`
Provider Provider `json:"provider,omitempty"`
Subscriber Subscriber `json:"subscriber,omitempty"`
ServiceInfo ServiceInfo `json:"service_info,omitempty"`
User User `json:"user,omitempty"`
RawProvider ProviderResponse `json:"raw_provider,omitempty"`
TrackingID string `json:"tracking_id,omitempty"`
Payer Payer `json:"payer,omitempty"`
Provider Provider `json:"provider,omitempty"`
Subscriber Subscriber `json:"subscriber,omitempty"`
ServiceInfo ServiceInfo `json:"service_info,omitempty"`
}
type Payer struct {

View File

@@ -1,16 +0,0 @@
package viewmodel
import (
"fmt"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
type ValidationError struct {
Errors []errors.ValidationError
Message string
}
func (ve *ValidationError) Error() string {
return fmt.Sprintf("Error: %s", ve.Message)
}

View File

@@ -1,14 +0,0 @@
package viewmodel
import "time"
type PasswordReset struct {
ID int64 `json:"-"`
UUID string `json:"uuid"`
User User `json:"user"`
Token string `json:"token"`
Created time.Time `json:"create_date"`
Expires time.Time `json:"expire_date"`
Used bool `json:"used"`
Opened bool `json:"opened"`
}

View File

@@ -1,15 +0,0 @@
package viewmodel
type Plan struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
InternalID string `json:"key,omitempty"`
Status bool `json:"desc,omitempty"`
PlanEntityID int64 `json:"plan_entity_id,omitempty"`
EntityID int64 `json:"entity_id,omitempty"`
PayerID int64 `json:"payer_id,omitempty"`
PayerName string `json:"payer_name,omitempty"`
PrefixID string `json:"prefix_uuid,omitempty"`
AlphaPrefix string `json:"alpha_prefix,omitempty"`
Active bool `json:"active,omitempty"`
}

View File

@@ -16,7 +16,6 @@ type ProviderResp struct {
Keys []ProviderKey `json:"keys,omitempty"`
Address ProviderAddress `json:"address,omitempty"`
Distance float64 `json:"distance,omitempty"`
Organization Organization `json:"organization,omitempty"`
}
type ProviderKey struct {

View File

@@ -14,53 +14,50 @@ type WebhookResponse struct {
//RideRequest has the data to dispatch a ride
type RideRequest struct {
UserUUID string `json:"user_uuid,omitempty"`
UserConsent bool `json:"user_consent,omitempty"`
Status string `json:"status,omitempty"`
RideID string `json:"ride_id,omitempty"`
RideType string `json:"ride_type,omitempty"`
Origin Location `json:"origin,omitempty"`
Location Location `json:"location,omitempty"`
Destination Location `json:"destination,omitempty"`
Passenger UserLyft `json:"passenger,omitempty"`
Notes string `json:"external_note,omitempty"`
RouteURL string `json:"route_url,omitempty"`
ScheduledPickupRange interface{} `json:"scheduled_pickup_range,omitempty"`
PrimetimePercentage string `json:"primetime_percentage,omitempty"`
Pickup Location `json:"pickup,omitempty"`
DropOff Location `json:"dropoff,omitempty"`
Vehicle Vehicle `json:"vehicle,omitempty"`
Price Price `json:"price,omitempty"`
Driver UserLyft `json:"driver,omitempty"`
GeneratedAtMS *int64 `json:"generated_at_ms,omitempty"`
GeneratedAt *time.Time `json:"generated_at,omitempty"`
RequestAtMS *int64 `json:"requested_at_ms,omitempty"`
RequestAt *time.Time `json:"requested_at,omitempty"`
LineItems []Price `json:"line_items,omitempty"`
BeaconColor string `json:"beacon_color,omitempty"`
Charges []Charge `json:"charges,omitempty"`
VisitDate *time.Time `json:"visit_date,omitempty"`
VisitTime *time.Time `json:"visit_time,omitempty"`
PickupTime *time.Time `json:"pickup_time,omitempty"`
ReturnTime *time.Time `json:"return_time,omitempty"`
Distance float64 `json:"distance,omitempty"`
ETA int64 `json:"eta,omitempty"`
Duration int64 `json:"duration,omitempty"`
Visit Visit `json:"visit,omitempty"`
CreateUserUUID string `json:"created_user_uuid,omitempty"`
VisitExternalID string `json:"visit_external_id,omitempty"`
CanCancel []string `json:"can_cancel,omitempty"`
PricingDetailsURL string `json:"pricing_details_url,omitempty"`
RideProfile string `json:"ride_profile,omitempty"`
DistanceInMiles float64 `json:"distance_miles,omitempty"`
DurationInSeconds float64 `json:"duration_seconds,omitempty"`
CanceledBy string `json:"canceled_by,omitempty"`
TripType TripType `json:"trip_type,omitempty"`
Error string `json:"error,omitempty"`
ErrorDescription string `json:"error_description,omitempty"`
User User `json:"user,omitempty"`
Provider ProviderResp `json:"provider,omitempty"`
RawProvider ProviderResponse `json:"raw_provider,omitempty"`
UserUUID string `json:"user_uuid,omitempty"`
UserConsent bool `json:"user_consent,omitempty"`
Status string `json:"status,omitempty"`
RideID string `json:"ride_id,omitempty"`
RideType string `json:"ride_type,omitempty"`
Origin Location `json:"origin,omitempty"`
Location Location `json:"location,omitempty"`
Destination Location `json:"destination,omitempty"`
Passenger UserLyft `json:"passenger,omitempty"`
Notes string `json:"external_note,omitempty"`
RouteURL string `json:"route_url,omitempty"`
ScheduledPickupRange interface{} `json:"scheduled_pickup_range,omitempty"`
PrimetimePercentage string `json:"primetime_percentage,omitempty"`
Pickup Location `json:"pickup,omitempty"`
DropOff Location `json:"dropoff,omitempty"`
Vehicle Vehicle `json:"vehicle,omitempty"`
Price Price `json:"price,omitempty"`
Driver UserLyft `json:"driver,omitempty"`
GeneratedAtMS *int64 `json:"generated_at_ms,omitempty"`
GeneratedAt *time.Time `json:"generated_at,omitempty"`
RequestAtMS *int64 `json:"requested_at_ms,omitempty"`
RequestAt *time.Time `json:"requested_at,omitempty"`
LineItems []Price `json:"line_items,omitempty"`
BeaconColor string `json:"beacon_color,omitempty"`
Charges []Charge `json:"charges,omitempty"`
VisitDate *time.Time `json:"visit_date,omitempty"`
VisitTime *time.Time `json:"visit_time,omitempty"`
PickupTime *time.Time `json:"pickup_time,omitempty"`
ReturnTime *time.Time `json:"return_time,omitempty"`
Distance float64 `json:"distance,omitempty"`
ETA int64 `json:"eta,omitempty"`
Duration int64 `json:"duration,omitempty"`
Visit Visit `json:"visit,omitempty"`
CreateUserUUID string `json:"created_user_uuid,omitempty"`
VisitExternalID string `json:"visit_external_id,omitempty"`
CanCancel []string `json:"can_cancel,omitempty"`
PricingDetailsURL string `json:"pricing_details_url,omitempty"`
RideProfile string `json:"ride_profile,omitempty"`
DistanceInMiles float64 `json:"distance_miles,omitempty"`
DurationInSeconds float64 `json:"duration_seconds,omitempty"`
CanceledBy string `json:"canceled_by,omitempty"`
TripType TripType `json:"trip_type,omitempty"`
Error string `json:"error,omitempty"`
ErrorDescription string `json:"error_description,omitempty"`
}
//Charge information
@@ -162,4 +159,4 @@ type RideRoute struct {
Duration int64 `json:"duration,omitempty"`
ETA int64 `json:"eta,omitempty"`
Bearing int64 `json:"bearing,omitempty"`
}
}

View File

@@ -13,7 +13,6 @@ type User struct {
BirthDate *time.Time `json:"birthdate,omitempty"`
Email *string `json:"email,omitempty"`
PhoneNumber *string `json:"phonenumber,omitempty"`
Type *string `json:"type,omitempty"`
Pass string `json:"pass,omitempty"`
Active bool `json:"active,omitempty"`
Created time.Time `json:"created,omitempty"`
@@ -24,9 +23,6 @@ type User struct {
Profiles []Profile `json:"profiles,omitempty"`
Types []OrganizationType `json:"types,omitempty"`
Organizations []Organization `json:"organizations,omitempty"`
Provider *ProviderResp `json:"provider,omitempty"`
Consent bool `json:"consent,omitempty"`
Test bool `json:"test,omitempty"`
}
type Contact struct {

View File

@@ -12,23 +12,22 @@ type VisitStatus struct {
// Visit entity data
type Visit struct {
UUID string `json:"visit_uuid,omitempty"`
Status VisitStatus `json:"visit_status,omitempty"`
User User `json:"user,omitempty"`
VisitDatetime time.Time `json:"visit_datetime,omitempty"`
VisitDuration int64 `json:"visit_duration,omitempty"`
PickupDatetime time.Time `json:"pickup_datetime,omitempty"`
Notes *string `json:"notes,omitempty"`
PickupAddressID int64 `json:"pickup_address_id,omitempty"`
DestinationAddressID int64 `json:"destination_address_id,omitempty"`
Pickup Location `json:"pickup,omitempty"`
Provider ProviderResp `json:"provider,omitempty"`
CreatedUser User `json:"created_user,omitempty"`
CreatedDate time.Time `json:"created,omitempty"`
UpdatedDate time.Time `json:"updated,omitempty"`
ReturnDate *time.Time `json:"return_date,omitempty"`
TripType TripType `json:"trip_type,omitempty"`
ExternalID string `json:"visit_external_id,omitempty"`
Rides []Ride `json:"rides,omitempty"`
RawProvider ProviderResponse `json:"raw_provider,omitempty"`
UUID string `json:"visit_uuid,omitempty"`
Status VisitStatus `json:"visit_status,omitempty"`
User User `json:"user,omitempty"`
VisitDatetime time.Time `json:"visit_datetime,omitempty"`
VisitDuration int64 `json:"visit_duration,omitempty"`
PickupDatetime time.Time `json:"pickup_datetime,omitempty"`
Notes *string `json:"notes,omitempty"`
PickupAddressID int64 `json:"pickup_address_id,omitempty"`
DestinationAddressID int64 `json:"destination_address_id,omitempty"`
Pickup Location `json:"pickup,omitempty"`
Provider ProviderResp `json:"provider,omitempty"`
CreatedUser User `json:"created_user,omitempty"`
CreatedDate time.Time `json:"created,omitempty"`
UpdatedDate time.Time `json:"updated,omitempty"`
ReturnDate *time.Time `json:"return_date,omitempty"`
TripType TripType `json:"trip_type,omitempty"`
ExternalID string `json:"visit_external_id,omitempty"`
Rides []Ride `json:"rides,omitempty"`
}

View File

@@ -1,8 +0,0 @@
package viewmodel
type Zipcode struct {
ID int64 `json:"-"`
UUID string `json:"uuid"`
Zipcode string `json:"zipcode"`
Participating bool `json:"participating"`
}

View File

@@ -113,10 +113,3 @@ p, BCBSIAD, *, bcbsi, *, *, *, /v1/nemt/eligibility, POST
p, BDCAD, *, techsupport, *, *, *, /v1/nemt/eligibility, POST
p, PLANAD, *, plan, *, *, *, /v1/nemt/eligibility, POST
p, AD, *, *, *, *, *, /v1/nemt/eligibility, POST
p, VIRPT, *, *, *, *, *, /v1/nemt/users/member, POST
p, VIRPT, *, *, *, *, *, /v1/nemt/users/member, GET
p, VIRPT, *, *, *, *, *, /v1/nemt/eligibility, POST
p, VIRPT, *, *, *, *, *, /v1/nemt/visits, POST
p, VIRPT, *, *, *, *, *, /v1/nemt/rides/eta, GET
p, VIRPT, *, *, *, *, *, /v1/nemt/provider, GET
p, VIRPT, *, *, *, *, *, /v1/selfregister, POST
1 p AD * * * * * * *
113 p BDCAD * techsupport * * * /v1/nemt/eligibility POST
114 p PLANAD * plan * * * /v1/nemt/eligibility POST
115 p AD * * * * * /v1/nemt/eligibility POST
p VIRPT * * * * * /v1/nemt/users/member POST
p VIRPT * * * * * /v1/nemt/users/member GET
p VIRPT * * * * * /v1/nemt/eligibility POST
p VIRPT * * * * * /v1/nemt/visits POST
p VIRPT * * * * * /v1/nemt/rides/eta GET
p VIRPT * * * * * /v1/nemt/provider GET
p VIRPT * * * * * /v1/selfregister POST

View File

@@ -4,7 +4,7 @@ pipelines:
master:
- step:
script:
- curl https://glide.sh/get -L -o - | sh
- curl https://glide.sh/get | sh
- mkdir -p /go/src/bitbucket.org/nemt/nemt-portal-api
- pwd
- ls -al
@@ -14,14 +14,11 @@ pipelines:
- rm -rf vendor/
- glide install -force
- go build -o nemt-portal-api
- mkdir -p dist/{static,docs,certs}
- mkdir -p dist/{static,docs}
- cp nemt-portal-api ./dist/
- cp -R static/* ./dist/static/
- cp -R docs/swagger/ ./dist/docs/
- cp -R certs/prd/* ./dist/certs/
- cp config.prd.toml ./dist/config.toml
- cp default.prd.conf ./dist/default.conf
- cp nginx.conf ./dist/nginx.conf
- cp authorization_model.conf ./dist/authorization_model.conf
- cp authorization_policy.csv ./dist/authorization_policy.csv
- docker build -f Dockerfile.run -t nemt-portal-api-run:prod --force-rm --build-arg BIN_NAME=nemt-portal-api --build-arg APP_NAME=nemt-portal-api .
@@ -36,7 +33,7 @@ pipelines:
development:
- step:
script:
- curl https://glide.sh/get -L -o - | sh
- curl https://glide.sh/get | sh
- mkdir -p /go/src/bitbucket.org/nemt/nemt-portal-api
- pwd
- ls -al
@@ -46,14 +43,11 @@ pipelines:
- rm -rf vendor/
- glide install -force
- go build -o nemt-portal-api
- mkdir -p dist/{static,docs,certs}
- mkdir -p dist/{static,docs}
- cp nemt-portal-api ./dist/
- cp -R static/* ./dist/static/
- cp -R docs/swagger/ ./dist/docs/
- cp -R certs/stg/* ./dist/certs/
- cp config.stg.toml ./dist/config.toml
- cp default.stg.conf ./dist/default.conf
- cp nginx.conf ./dist/nginx.conf
- cp authorization_model.conf ./dist/authorization_model.conf
- cp authorization_policy.csv ./dist/authorization_policy.csv
- docker build -f Dockerfile.run -t nemt-portal-api-run:dev --force-rm --build-arg BIN_NAME=nemt-portal-api --build-arg APP_NAME=nemt-portal-api .

View File

@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0VyKNSM/a/CzE
16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/
ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK
qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p
oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK
uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts
l5njh/MhAgMBAAECggEAHSE+CYhLWtoE+T7FGu1YjBvwNxc5TlSEN0qVkpixE+k9
Ndl+r+txjEaq9xRPIJE48LWVynC5DqFhx/lC7K9n6JIgsdz9ijlQuHau2W3adAmo
pfReHscVn5ofJ0/X3j2jSMP3Q3fxJmGwQza3pz/dH8kn+7SkMuXqABYm1peUeXCr
BOIl0/C9UpuIlDrK0TL4VVC3gR/sXSTJV7CV12o6mqWMc5eRjYdz5Tn3W6yC5Cir
GrI3zHEDnhUM8xMtLHTxJ41Sim8To1NSuSrUk9Zd/sEQfT1daqYM3jPnfCePgzOH
b6zDzKwIDqb8T0LOOnn9uDjgz3TkRzkfEhw4xJE36QKBgQDmeR7mkENRtU5+DErI
vKWv1+SfUklfzrhgr/MqmNzvBmgqV9shVWPPg4TtERL+kiPvTFVWmAvUcC81h0Bx
ztGg49067reZq0bEYSCNaCvDvNGf9i2wirWpdOxofLI7AONcWQMm7pIwA+/ph0tG
liW6Q4Ppl4/qQfiHQ/fyqOBzXwKBgQDIUIpbUFslaEhPwAPlPAgulzu0uZxG99TG
Qxl5JKQapv5WlJ1HzU6EtMrMS4p+8Hkq2x6SRQnteZTBCvgi61eHauw7MfswhNFi
elZW7AHzydoNM+mJV8pWIVhfNtnQkVsmu0Id/dXo7U/6qWMK1yEbICAqsBkZIdfM
6EQTWxupfwKBgDK168qna2iLEB5D7iCFAZ/TTQaRQHvILGF51XNF9zbQnhLTCfAn
rbJ3KcRPwXIqDaYVkaFgCxpPJNQOUmu4Kf/Qo1jYNaWmPgfvpw32IcsLvMQJkrwJ
iTcj9vB2n3DEHUKwgzUJwTi3ZQ5pKnL5jouRV3EKXCwbH+gDWIcYCWrZAoGBALs6
BEebEMYi9UuNFlcBSEh71DN0NOxkIfz5pGqFY9kBcsHsACGndJc3AEH47Ub+btIu
oiFm5AORWwcfwJOq0lHhD1G4wqYzzh00aVSvHJgHd4ZVmhdj9duRKS89blKyObc2
2XJ82Z3viYypG8h7ERdwbIBZveuupSyBf3dz9aPzAoGBAKSN9nskGkSMfPdPlohA
BAmZGciAbob0un6db34ahExKEfkjhPA/C1AIs6LZz9QNy/OTUlXzVSx4axHMeqxo
HAb5yVRkj2VDBnWl//BEAxXKj+r1KOqESdqaKeQcYzXzAMQ36DJia7DOiej7HNSx
Y3ydXe8hO8lutgiU5rsBNVLM
-----END PRIVATE KEY-----

View File

@@ -1,88 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGvjCCBaagAwIBAgIQC3nVkJVbuOa1WFfJQc+IMDANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN
MjAwNTIwMTIwMDAwWjCBhTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz
MRAwDgYDVQQHEwdDaGljYWdvMS8wLQYDVQQKEyZCbHVlIENyb3NzIGFuZCBCbHVl
IFNoaWVsZCBBc3NvY2lhdGlvbjEgMB4GA1UEAwwXKi5kZXYuYmNic2luc3RpdHV0
ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0VyKNSM/a/CzE
16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/
ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK
qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p
oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK
uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts
l5njh/MhAgMBAAGjggNfMIIDWzAfBgNVHSMEGDAWgBQPgGEcgjFh1S8o541GOLQs
4cbZ4jAdBgNVHQ4EFgQUOlOHeILArFmCfRgy4zob9YD7ZdMwIgYDVR0RBBswGYIX
Ki5kZXYuYmNic2luc3RpdHV0ZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8v
Y3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDov
L2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3
BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu
Y29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho
dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl
cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw
CQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHYApLkJkLQYWBSH
uxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFjhC1vrQAABAMARzBFAiEAjDaMTkKz
JL1M7AloHKciZwIm9PhTpRJhtDedIoV2l5oCIEyT5kke4/OXoBE9guw1TPCKwuS5
klDOeG+rlHiTHZvbAHcAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMA
AAFjhC1xQwAABAMASDBGAiEAzo+0zJUoqV0X0IqzaZ+9boXzWvIzZCR/OqT1qcAe
a3QCIQCdMYaIEYnhnsaOXPMsyShv+ry41lQ9UvUZ3EAvhjgCeQB3ALvZ37wfinG1
k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABY4QtcKQAAAQDAEgwRgIhAJ4XGViz
vfkGsR3/UWlVZhX9t5rLAlyhW/t1K17vkNjJAiEAhzQycmcTPIVb1Ul1Ug5UgWQ4
eD2rp/4raewQVACs26QwDQYJKoZIhvcNAQELBQADggEBADjGzhdcyCYxemKuWoP9
Umd0jnS6gHPivwgpy2Ra4SSsFCkucHX8dRMi63MRghiKi4FPj9LsFoLpdHacfi+6
Q1lX3fZ6Mv2ZpNjMtBe/g6SATLsFxUQl+UP5bMShEXHsQduinAvSW3m8UpQZ2UxG
7L/XmNfeW8x213Mi4G2DNUJKDMjO28bO/GbCNB85HGfhnaDxj7OsQYllbE5oEDXN
Wkx1QZFrvqE3/2zoOa1ga36xymRXt0Sn3OSFr/ukZh3MCWAL5fuT4zjnSjybHDqT
2qdmV08ECgXwVNUMtbTFq9kenBN0xTrfPFR0Y0IPzqXQP5kTPktgrrYiAf+S875J
IVo=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----

View File

@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCs4SiZVk5EI7BQ
c43SAmeAriEKoxLb0d32fCXltF/hbFouMDVA3h5TacTTVCH9JrKIykV2hbJXd8DM
UUOO0gAJ6DOjvmHeDrUquT3+eXqX71QLGVKSVgcDBy+IjdSlNj1RDdxT1gBKdWYj
OHFHsFZgGZc1OysXiww9mUhx+JhFSq5EOo7jVM6/uOfA7dXazk6sCxiT+SuEN9Hh
uPZdlHUnf+S/BPDI1PK90AG6Wj8U+nroWZZ8ZMGyh10FBLnmdZ30iO7Ll73leqR4
7rF9Ox4w4DDwWYaaiNWX3CvneYUdmTCUPJC5G82AYlMVZ9dVloIOYPMz1XwH9gs1
vzwCAH2lAgMBAAECggEAYOUh2C+jVlWacL0Tc+2dDWaLZmbYHxSVj50tsH1UcAhG
0zR55I2Z+a6Cft/c3QJfdoPIQxHUT2nzSZESiG3zT5oxt0jxmYAs0nFY6dQ0fgvJ
0x6yRQqqi2vvnF3CHYc0/sUCBIshRppeUMdF1qRjBSHSuicbk+p/Rdcv35Ex50Nz
rskvhtmPU0b7B/tVyvp+pLD+5uC42epW4Eh7R2er7WWp6m8e6mh9gjn1TYLdbprV
p/SNTJnGp4dUNO851wgsqeJcokGA6wdOb3UxIcEbW7EvX5ybozVZfUk3vP5toTmS
bNCm0UlwELE7+zX21ka7Wrfc5vGLYsdRE0Pa3V3X0QKBgQDj0E/sQ8lApJzlKf8T
9GEcuf7NM1f9DHeUmj2N8v055uAqUcE3h7PdUWSrJCbotowrJQ3jGTJd1uFrQVI4
4FEgestZDYaJ/8Bq7xt8cuebfTHzYj/o3ace4uAUKKfpxJz8+WzIK42mrcMDC221
HMmV5A4IFaM6bsvCia/LXJ91iwKBgQDCROGH8bFeriXOk8QXoq6Vq1paxEtukWBH
dtKcsAqJsUtKsVWclei+XucBrN0lrzDBii/ewcq/EH2GEknGwg0ooTG0mUD9nbCu
L9a3NUxBLxdKLZaDVsl7sxkbL9HIn4yGvznqfo4rjA4X8jY5OB7X6oR8yWdKhFJf
dT8Yi1YfjwKBgQCtSLSiaGVa0FuvTKSDzy1XJnsUJuvUxXjoBfKwWJYZRu5YAlvQ
G17LB7BlJVibRs+Tudm4VmAjVOGeLc+XB7lt1Tl8AXfG3EzGih4EKXrWoQIvuRoX
zRHjwnrjmpEulak8G5WNJOPYVu+xDy5hxwXnB9NMfvjr538B+K1JKKj6RQKBgHmI
K+sm2YZYvdAhAvCiVkPNocXcvS/bhHbQr+tT+hOvtWFx1RQTeDn4Ft4mbWbQ1ViO
gWoCpDqpL027jSnpZeAAD59irJS8nLYruVB96ElzE0fVgy6BEaTwIwmt/bhbj8cQ
REQdjgVSJdL3NNLQ+AKtdNq4CIVGiF2tdJ5/NI6jAoGBAJnsp+bti4F+LrQVPMNb
Ptyxw1eOfNkjqyoAJQXJ6HBN3uDVes/peR+9k4ATsZRMUyo+P07ggAo397+i8PY2
FeAwbzACVIb0TVNki8dP/U30e7087DgyxzMK9/ggeCuzcHczEekkioTVQubfd5vJ
4N4yQGflInls/OMIodPBir1j
-----END PRIVATE KEY-----

View File

@@ -1,88 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGxzCCBa+gAwIBAgIQDARDXxHDhGyEB0wVou2tYTANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN
MjAwNTIwMTIwMDAwWjCBgTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz
MRAwDgYDVQQHEwdDaGljYWdvMS8wLQYDVQQKEyZCbHVlIENyb3NzIGFuZCBCbHVl
IFNoaWVsZCBBc3NvY2lhdGlvbjEcMBoGA1UEAwwTKi5iY2JzaW5zdGl0dXRlLmNv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKzhKJlWTkQjsFBzjdIC
Z4CuIQqjEtvR3fZ8JeW0X+FsWi4wNUDeHlNpxNNUIf0msojKRXaFsld3wMxRQ47S
AAnoM6O+Yd4OtSq5Pf55epfvVAsZUpJWBwMHL4iN1KU2PVEN3FPWAEp1ZiM4cUew
VmAZlzU7KxeLDD2ZSHH4mEVKrkQ6juNUzr+458Dt1drOTqwLGJP5K4Q30eG49l2U
dSd/5L8E8MjU8r3QAbpaPxT6euhZlnxkwbKHXQUEueZ1nfSI7suXveV6pHjusX07
HjDgMPBZhpqI1ZfcK+d5hR2ZMJQ8kLkbzYBiUxVn11WWgg5g8zPVfAf2CzW/PAIA
faUCAwEAAaOCA2wwggNoMB8GA1UdIwQYMBaAFA+AYRyCMWHVLyjnjUY4tCzhxtni
MB0GA1UdDgQWBBQLp7ndHlG3iCGf7P7Np16aWJn+fzAxBgNVHREEKjAoghMqLmJj
YnNpbnN0aXR1dGUuY29tghFiY2JzaW5zdGl0dXRlLmNvbTAOBgNVHQ8BAf8EBAMC
BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMGsGA1UdHwRkMGIwL6At
oCuGKWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzYuY3JsMC+g
LaArhilodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDBM
BgNVHSAERTBDMDcGCWCGSAGG/WwBATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3
dy5kaWdpY2VydC5jb20vQ1BTMAgGBmeBDAECAjB8BggrBgEFBQcBAQRwMG4wJAYI
KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBGBggrBgEFBQcwAoY6
aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMlNlY3VyZVNl
cnZlckNBLmNydDAJBgNVHRMEAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgA
dgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWOELVu6AAAEAwBH
MEUCIAZMGHS0chj0XWT4ikeIjqg0dglEBDIavlnouMrAEiCnAiEAzFN2rUdA0N/l
+cJqOaEJHIop81RoAcrQ8ltrNkXdZD8AdgBvU3asMfAxGdiZAKRRFf93FRwR2QLB
ACkGjbIImjfZEwAAAWOELV3xAAAEAwBHMEUCIFojBHhsdHar7n0eJ35etIlqUtHR
WV9EQxu752OWrnmsAiEAod+vqZXLOUYR4DRzlA3h9BBkkm0hc4QAU2v2h9h46rQA
dgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAWOELVwOAAAEAwBH
MEUCIEBiLv2mAcIhhIHNmCKFFxQM6UtbO4XmlNNm9PTQLtxEAiEAichicElMgsp9
wAXBuHQ5stQiDicsJ/04Ws2QzuxbpTQwDQYJKoZIhvcNAQELBQADggEBAB3kQbAX
/RaGmnyIduvFE66Nzd/goThIr4bpBnrW0YKvZj2oHq34KjaVkmWX4VXHmyHTd9TI
YJyHifiMrfZ/BCkS5FDg32J1Vocp89k5YDS+pHxlLLxqqMsrz80v5mtblhDhqenx
2dsdwYErlbrAvNp95BKdwqcVbqvg2IHBhJ8myB5kgGLgU6Sn96SfsF5wytW+qnQx
gIn3qfPkwXVou/mq8PbZSqsrNvggjOTKbkNj8k4u+/OAHd9nP4p/CBGN7hb5RxXs
e24Ql2MFqKXx2EIrsMs+ow2xnz6hNRAD39vsYp7HSFj7Ph32Wi8X1O+J68PiNbaW
ZblXGGMRXKXUfFA=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----

View File

@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0VyKNSM/a/CzE
16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/
ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK
qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p
oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK
uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts
l5njh/MhAgMBAAECggEAHSE+CYhLWtoE+T7FGu1YjBvwNxc5TlSEN0qVkpixE+k9
Ndl+r+txjEaq9xRPIJE48LWVynC5DqFhx/lC7K9n6JIgsdz9ijlQuHau2W3adAmo
pfReHscVn5ofJ0/X3j2jSMP3Q3fxJmGwQza3pz/dH8kn+7SkMuXqABYm1peUeXCr
BOIl0/C9UpuIlDrK0TL4VVC3gR/sXSTJV7CV12o6mqWMc5eRjYdz5Tn3W6yC5Cir
GrI3zHEDnhUM8xMtLHTxJ41Sim8To1NSuSrUk9Zd/sEQfT1daqYM3jPnfCePgzOH
b6zDzKwIDqb8T0LOOnn9uDjgz3TkRzkfEhw4xJE36QKBgQDmeR7mkENRtU5+DErI
vKWv1+SfUklfzrhgr/MqmNzvBmgqV9shVWPPg4TtERL+kiPvTFVWmAvUcC81h0Bx
ztGg49067reZq0bEYSCNaCvDvNGf9i2wirWpdOxofLI7AONcWQMm7pIwA+/ph0tG
liW6Q4Ppl4/qQfiHQ/fyqOBzXwKBgQDIUIpbUFslaEhPwAPlPAgulzu0uZxG99TG
Qxl5JKQapv5WlJ1HzU6EtMrMS4p+8Hkq2x6SRQnteZTBCvgi61eHauw7MfswhNFi
elZW7AHzydoNM+mJV8pWIVhfNtnQkVsmu0Id/dXo7U/6qWMK1yEbICAqsBkZIdfM
6EQTWxupfwKBgDK168qna2iLEB5D7iCFAZ/TTQaRQHvILGF51XNF9zbQnhLTCfAn
rbJ3KcRPwXIqDaYVkaFgCxpPJNQOUmu4Kf/Qo1jYNaWmPgfvpw32IcsLvMQJkrwJ
iTcj9vB2n3DEHUKwgzUJwTi3ZQ5pKnL5jouRV3EKXCwbH+gDWIcYCWrZAoGBALs6
BEebEMYi9UuNFlcBSEh71DN0NOxkIfz5pGqFY9kBcsHsACGndJc3AEH47Ub+btIu
oiFm5AORWwcfwJOq0lHhD1G4wqYzzh00aVSvHJgHd4ZVmhdj9duRKS89blKyObc2
2XJ82Z3viYypG8h7ERdwbIBZveuupSyBf3dz9aPzAoGBAKSN9nskGkSMfPdPlohA
BAmZGciAbob0un6db34ahExKEfkjhPA/C1AIs6LZz9QNy/OTUlXzVSx4axHMeqxo
HAb5yVRkj2VDBnWl//BEAxXKj+r1KOqESdqaKeQcYzXzAMQ36DJia7DOiej7HNSx
Y3ydXe8hO8lutgiU5rsBNVLM
-----END PRIVATE KEY-----

View File

@@ -1,88 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIGvjCCBaagAwIBAgIQC3nVkJVbuOa1WFfJQc+IMDANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN
MjAwNTIwMTIwMDAwWjCBhTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz
MRAwDgYDVQQHEwdDaGljYWdvMS8wLQYDVQQKEyZCbHVlIENyb3NzIGFuZCBCbHVl
IFNoaWVsZCBBc3NvY2lhdGlvbjEgMB4GA1UEAwwXKi5kZXYuYmNic2luc3RpdHV0
ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0VyKNSM/a/CzE
16vidZzip1p4B7+EhJVyENoofRDk7D7afDddWV33yHUvI5opsyKIEMuGFRNIROH/
ZX47vV3H2ST/5UmkXhghEVjA/xQFUqx2hUxAjI+EkHyf+D3cofcoqFBGA7DVQ9MK
qgbRmwV09IgfQmdlFlF/D3/ZROYNYhY7NC5W+9d+JdmkV45Kp2zIDEa990roDF2p
oN6Nk0WsDMNn5nhyFtGyeuFmYcWwKeCI/XlMu5roko7tJtY0oC0boKSZ8S7xiEPK
uBUxw9cWcHVbkLyeJXIr7lfIzg5xejX3A5/KA7UuKtPAc3HQh09TEOD40Rof5Mts
l5njh/MhAgMBAAGjggNfMIIDWzAfBgNVHSMEGDAWgBQPgGEcgjFh1S8o541GOLQs
4cbZ4jAdBgNVHQ4EFgQUOlOHeILArFmCfRgy4zob9YD7ZdMwIgYDVR0RBBswGYIX
Ki5kZXYuYmNic2luc3RpdHV0ZS5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW
MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8v
Y3JsMy5kaWdpY2VydC5jb20vc3NjYS1zaGEyLWc2LmNybDAvoC2gK4YpaHR0cDov
L2NybDQuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwTAYDVR0gBEUwQzA3
BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu
Y29tL0NQUzAIBgZngQwBAgIwfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhho
dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNl
cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQw
CQYDVR0TBAIwADCCAYAGCisGAQQB1nkCBAIEggFwBIIBbAFqAHYApLkJkLQYWBSH
uxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFjhC1vrQAABAMARzBFAiEAjDaMTkKz
JL1M7AloHKciZwIm9PhTpRJhtDedIoV2l5oCIEyT5kke4/OXoBE9guw1TPCKwuS5
klDOeG+rlHiTHZvbAHcAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMA
AAFjhC1xQwAABAMASDBGAiEAzo+0zJUoqV0X0IqzaZ+9boXzWvIzZCR/OqT1qcAe
a3QCIQCdMYaIEYnhnsaOXPMsyShv+ry41lQ9UvUZ3EAvhjgCeQB3ALvZ37wfinG1
k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABY4QtcKQAAAQDAEgwRgIhAJ4XGViz
vfkGsR3/UWlVZhX9t5rLAlyhW/t1K17vkNjJAiEAhzQycmcTPIVb1Ul1Ug5UgWQ4
eD2rp/4raewQVACs26QwDQYJKoZIhvcNAQELBQADggEBADjGzhdcyCYxemKuWoP9
Umd0jnS6gHPivwgpy2Ra4SSsFCkucHX8dRMi63MRghiKi4FPj9LsFoLpdHacfi+6
Q1lX3fZ6Mv2ZpNjMtBe/g6SATLsFxUQl+UP5bMShEXHsQduinAvSW3m8UpQZ2UxG
7L/XmNfeW8x213Mi4G2DNUJKDMjO28bO/GbCNB85HGfhnaDxj7OsQYllbE5oEDXN
Wkx1QZFrvqE3/2zoOa1ga36xymRXt0Sn3OSFr/ukZh3MCWAL5fuT4zjnSjybHDqT
2qdmV08ECgXwVNUMtbTFq9kenBN0xTrfPFR0Y0IPzqXQP5kTPktgrrYiAf+S875J
IVo=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----

View File

@@ -1,7 +1,6 @@
[app]
name = "nemt"
debug = true
disable-zip-validation = true
[app.docs]
swagger-path = "./static/swagger-ui"
@@ -81,7 +80,4 @@ secret = "hK4Yc9jtBrxaZTr4UU2VsfX9"
[blue365]
url = "https://api-cloud.bcbs.com/blue365deals-stg/v1/validatePrefix/"
key = "jcn5xjxvarc96rtjxp25dctj"
secret = "6XdEusG2w2PWWXsfXVyweQnY"
[eligibility]
url = "https://portal-api.dev.bcbsinstitute.com/v1/nemt/eligibility"
secret = "6XdEusG2w2PWWXsfXVyweQnY"

View File

@@ -1,7 +1,6 @@
[app]
name = "nemt"
debug = true
disable-zip-validation = true
[app.docs]
swagger-path = "/opt/app/nemt-portal-api/static/swagger-ui"
@@ -10,7 +9,7 @@ disable-zip-validation = true
[db]
host = "db01.cj5318jcaupw.us-east-2.rds.amazonaws.com"
port = 3306
name = "nemt"
name = "nemt_clean"
user = "nemt-user"
pass = "OL&!n#p6J8Lu"
max-life-minutes = 5
@@ -75,13 +74,10 @@ user-uuid = "11a49fa4-fbc7-4fe9-87fe-52a5bc3b71f8"
[bxe]
url = "https://api-pve.bcbs.com/BXDirectConnect/V30"
key = "c63z7gv9a5qz2zgx7zcm3253"
secret = "hK4Yc9jtBrxaZTr4UU2VsfX9"
key = "dacg7jtsmb6ajr3z553jbczg"
secret = "vFhNeWE8JdJpbDZQtcm6AHjX"
[blue365]
url = "https://api-cloud.bcbs.com/blue365deals-stg/v1/validatePrefix/"
key = "jcn5xjxvarc96rtjxp25dctj"
secret = "6XdEusG2w2PWWXsfXVyweQnY"
[eligibility]
url = "https://portal-api.bcbsinstitute.com/v1/nemt/eligibility"

View File

@@ -1,7 +1,6 @@
[app]
name = "nemt"
debug = true
disable-zip-validation = true
[app.docs]
swagger-path = "/opt/app/nemt-portal-api/static/swagger-ui"

View File

@@ -20,17 +20,14 @@ var (
// Conn is the MySQL connection manager
type Conn struct {
db *sql.DB
users *userRepo
rides *rideRepo
visit *visitRepo
provider *providerRepo
notification *notificationRepo
profile *profileRepo
organization *organizationRepo
zipcodes *zipcodeRepo
plan *planRepo
passwordReset *passwordResetRepo
db *sql.DB
users *userRepo
rides *rideRepo
visit *visitRepo
provider *providerRepo
notification *notificationRepo
profile *profileRepo
organization *organizationRepo
}
// Begin starts a transaction
@@ -83,18 +80,6 @@ func (c *Conn) Organization() contract.OrganizationRepo {
return c.organization
}
func (c *Conn) Zipcodes() contract.ZipcodeRepo {
return c.zipcodes
}
func (c *Conn) Plans() contract.PlanRepo {
return c.plan
}
func (c *Conn) PasswordReset() contract.PasswordResetRepo {
return c.passwordReset
}
// Instance returns an instance of a DataManager
func Instance(cfg *config.Config) (contract.DataManager, error) {
once.Do(func() {
@@ -126,9 +111,6 @@ func Instance(cfg *config.Config) (contract.DataManager, error) {
instance.notification = newNotificationRepo(db)
instance.profile = newProfileRepo(db)
instance.organization = newOrganizationRepo(db)
instance.zipcodes = newZipcodeRepo(db)
instance.plan = newPlanRepo(db)
instance.passwordReset = newPasswordResetRepo(db)
})
return instance, connErr

View File

@@ -24,11 +24,6 @@ func (c *organizationRepo) getProfileQuery(user entity.User) (query string, wher
if len(user.Profiles) > 0 {
for _, p := range user.Profiles {
switch p.Key {
case "VIRPT":
switch p.Organization.Type.Key {
case "provider":
return
}
case "AD", "BCBSIAD", "BDCAD", "PLANAD":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa":
@@ -219,11 +214,7 @@ func (c *organizationRepo) parseEntity(row scanner) (retVal entity.Organization,
err = row.Scan(
&retVal.ID, &retVal.UUID, &retVal.Type.ID, &retVal.Type.Name, &retVal.Type.Key, &retVal.Name, &retVal.Description, &retVal.ReferenceID, &retVal.ParentID, &retVal.Main, &retVal.Created, &retVal.Updated, &retVal.Active, &retVal.Suspended, &retVal.Blocked, &retVal.Author.ID, &retVal.Author.UUID, &retVal.Author.Name, &retVal.LastEditor.ID, &retVal.LastEditor.UUID, &retVal.LastEditor.Name)
if err == sql.ErrNoRows {
return retVal, nil
} else {
return retVal, errors.Wrap(err)
}
return retVal, errors.Wrap(err)
}
// parseSet parses a result set result to an entity array
@@ -346,6 +337,7 @@ func (c *organizationRepo) GetByUUID(organizationUUID string, user entity.User)
}
query = c.getQuery() + query + " WHERE a.organization_uuid = ? " + where
return c.parseEntity(c.conn.QueryRow(query, organizationUUID))
}
@@ -360,17 +352,6 @@ func (c *organizationRepo) GetByID(organizationID int64, user entity.User) (enti
return c.parseEntity(c.conn.QueryRow(query, organizationID))
}
func (c *organizationRepo) GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error) {
query, where, err := c.getProfileQuery(user)
if err != nil {
return entity.Organization{}, err
}
query = c.getQuery() + query + " WHERE b.organization_type_key = ? AND a.organization_reference_id = ? " + where
return c.parseEntity(c.conn.QueryRow(query, typeKey, referenceID))
}
func (c *organizationRepo) GetChildsByID(organizationID int64, user entity.User) ([]entity.Organization, error) {
query, where, err := c.getProfileQuery(user)
if err != nil {
@@ -450,16 +431,13 @@ func (c *organizationRepo) SetOrganizationAddress(address entity.OrganizationAdd
return entity.OrganizationAddress{}, errors.NewNotFoundError()
}
if address.Organization.ID == 0 {
organization, err := c.GetByUUID(address.Organization.UUID, user)
if err != nil {
return entity.OrganizationAddress{}, err
}
address.Organization = &organization
organization, err := c.GetByUUID(address.Organization.UUID, user)
if err != nil {
return entity.OrganizationAddress{}, err
}
UUID, _ := uuid.NewV4()
result, err := c.conn.Exec(query, UUID.String(), address.Organization.ID, address.InternalID, address.Name, address.Address, address.Description, address.Latitude, address.Longitude, address.CreatedUser.ID, address.UpdatedUser.ID)
result, err := c.conn.Exec(query, UUID.String(), organization.ID, address.InternalID, address.Name, address.Address, address.Description, address.Latitude, address.Longitude, address.CreatedUser.ID, address.UpdatedUser.ID)
if err != nil {
return entity.OrganizationAddress{}, err
}

View File

@@ -1,144 +0,0 @@
package datamysql
import (
"database/sql"
"fmt"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
uuid "github.com/satori/go.uuid"
)
// rideRepo maps methods to database
type passwordResetRepo struct {
conn executor
}
func newPasswordResetRepo(conn executor) *passwordResetRepo {
return &passwordResetRepo{
conn: conn,
}
}
func (c *passwordResetRepo) getQuery() string {
const (
query = `SELECT
a.password_reset_id,
a.password_reset_uuid,
a.user_id,
b.user_uuid,
a.token,
a.create_date,
a.expire_date,
(IFNULL(a.used, b'0') = b'1') used,
(IFNULL(a.opened, b'0') = b'1') opened
FROM
tab_password_reset a
INNER JOIN tab_user b
ON a.user_id = b.user_id`
)
return query
}
// parseSet parses a result set result to an entity array
func (c *passwordResetRepo) parseSet(rows *sql.Rows, err error) ([]entity.PasswordReset, error) {
if err != nil {
return nil, errors.Wrap(err)
}
result := make([]entity.PasswordReset, 0)
for rows.Next() {
entity, err := c.parseEntity(rows)
if err != nil {
return nil, errors.Wrap(err)
}
result = append(result, entity)
}
return result, nil
}
// parseEntity parses a result to an entity
func (c *passwordResetRepo) parseEntity(row scanner) (retVal entity.PasswordReset, err error) {
err = row.Scan(
&retVal.ID, &retVal.UUID, &retVal.User.ID, &retVal.User.UUID, &retVal.Token, &retVal.Created, &retVal.Expires, &retVal.Used, &retVal.Opened)
return retVal, errors.Wrap(err)
}
func (c *passwordResetRepo) GetAll() ([]entity.PasswordReset, error) {
return c.parseSet(c.conn.Query(c.getQuery()))
}
func (c *passwordResetRepo) CreatePasswordResetEntry(passwordResetEntry entity.PasswordReset) (entity.PasswordReset, error) {
const (
insertQuery = `INSERT INTO tab_password_reset(password_reset_uuid, user_id, token, expire_date, used, opened) VALUES(?, ?, ?, ?, 0, 0);`
)
retVal := passwordResetEntry
guid, _ := uuid.NewV4()
userRepo := newUserRepo(c.conn)
fullUser, err := userRepo.GetByEmail(passwordResetEntry.User.Email)
if err != nil {
return retVal, err
}
if fullUser.Email != passwordResetEntry.User.Email {
return retVal, fmt.Errorf("User not found")
}
results, err := c.conn.Exec(insertQuery, guid, fullUser.ID, passwordResetEntry.Token, passwordResetEntry.Expires)
if err != nil {
return retVal, err
}
retVal.ID, err = results.LastInsertId()
if err != nil {
return retVal, err
}
return c.GetByID(retVal.ID)
}
func (c *passwordResetRepo) GetByID(ID int64) (entity.PasswordReset, error) {
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.password_reset_id = ?; ", ID))
}
func (c *passwordResetRepo) GetByToken(token string) (entity.PasswordReset, error) {
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE a.token = ? AND a.used = 0; ", token))
}
func (c *passwordResetRepo) SetTokenOpened(token string) error {
const (
query = `UPDATE tab_password_reset a
SET a.opened = 1
WHERE a.token = ? AND a.used = 0 AND a.expire_date > CURRENT_TIMESTAMP`
)
result, err := c.conn.Exec(query, token)
if err != nil {
return err
}
if updateCount, err := result.RowsAffected(); err != nil || updateCount == 0 {
return fmt.Errorf("Invalid token")
}
return nil
}
func (c *passwordResetRepo) SetTokenUsed(token string) error {
const (
query = `UPDATE tab_password_reset a
SET a.opened = 1,
a.used = 1
WHERE a.token = ? AND a.used = 0`
)
if _, err := c.conn.Exec(query, token); err != nil {
return err
}
return nil
}

View File

@@ -1,82 +0,0 @@
package datamysql
import (
"database/sql"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
type planRepo struct {
conn executor
}
func newPlanRepo(conn executor) *planRepo {
return &planRepo{
conn: conn,
}
}
func (c *planRepo) getQuery() string {
const query = `SELECT
a.plan_id,
a.plan_uuid,
a.plan_name,
a.plan_internal_id,
a.plan_internal_status,
a.plan_entity_id,
a.entity_id,
a.payer_id,
a.payer_name,
a.active,
a.created,
a.updated,
b.plan_prefix_id,
b.plan_prefix_uuid,
b.alpha_prefix
FROM
tab_plan a
INNER JOIN
tab_plan_alpha_prefix b ON a.plan_id = b.plan_id `
return query
}
func (c *planRepo) parseSet(rows *sql.Rows, err error) ([]entity.Plan, error) {
if err != nil {
return nil, errors.Wrap(err)
}
result := make([]entity.Plan, 0)
for rows.Next() {
entity, err := c.parseEntity(rows)
if err != nil {
return nil, errors.Wrap(err)
}
result = append(result, entity)
}
return result, nil
}
func (c *planRepo) parseEntity(row scanner) (retVal entity.Plan, err error) {
err = row.Scan(
&retVal.ID, &retVal.UUID, &retVal.Name, &retVal.InternalID, &retVal.Status, &retVal.PlanEntityID, &retVal.EntityID, &retVal.PayerID, &retVal.PayerName,
&retVal.Active, &retVal.Created, &retVal.Updated, &retVal.PrefixID, &retVal.PrefixUUID, &retVal.AlphaPrefix)
return retVal, errors.Wrap(err)
}
func (c *planRepo) GetByAlphaPrefix(alphaPrefix string) (entity.Plan, error) {
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE b.alpha_prefix = ? ", alphaPrefix))
}
func (c *planRepo) GetByUUID(planUUID string) ([]entity.Plan, error) {
return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.plan_uuid = ? ", planUUID))
}
func (c *planRepo) GetByID(planID int64) ([]entity.Plan, error) {
return c.parseSet(c.conn.Query(c.getQuery()+" WHERE a.plan_id = ? ", planID))
}
func (c *planRepo) GetByPrefixUUID(prefixUUID string) (entity.Plan, error) {
return c.parseEntity(c.conn.QueryRow(c.getQuery()+" WHERE b.plan_prefix_uuid = ? ", prefixUUID))
}

View File

@@ -27,7 +27,7 @@ func (c *providerRepo) getProfileQuery(user entity.User) (query string, where st
if len(user.Profiles) > 0 {
for _, p := range user.Profiles {
switch p.Key {
case "AD", "BCBSIAD", "BDCAD", "PLANAD", "VIRPT":
case "AD", "BCBSIAD", "BDCAD", "PLANAD":
return
case "SP", "SPT":
switch p.Organization.Type.Key {
@@ -72,44 +72,44 @@ func (c *providerRepo) getSelectQueryBaseKey() string {
func (c *providerRepo) getSelectQueryBase() string {
return `SELECT DISTINCT
a.provider_id,
a.provider_uuid,
a.provider_internal_id,
IFNULL(a.provider_internal_id_suffix, '') provider_internal_id_suffix,
IFNULL(a.provider_muk_id, '') provider_muk_id,
IFNULL(a.organization_name, '') organization_name,
IFNULL(a.gender, '') gender,
IFNULL(a.accept_new_patients, '') accept_new_patients,
IFNULL(a.provider_name, '') provider_name,
IFNULL(a.first_name, '') first_name,
IFNULL(a.last_name, '') last_name,
IFNULL(a.middle_name, '') middle_name,
IFNULL(a.provider_title, '') provider_title,
IFNULL(a.street_name1, '') street_name1,
IFNULL(a.street_name2, '') street_name2,
IFNULL(a.city_name, '') city_name,
IFNULL(a.state, '') state,
IFNULL(a.zipcode, '') zipcode,
IFNULL(a.country, '') country,
IFNULL(a.latitude, 0) latitude,
IFNULL(a.longitude, 0) longitude,
IFNULL(a.phone_number, '') phone_number,
a.create_at,
a.update_at,
a.active,
a.enabled,
a.created_user,
(3959 * acos (
cos ( radians(?) )
* cos( radians( IFNULL(a.latitude, 0) ) )
* cos( radians( IFNULL(a.longitude, 0) ) - radians(?) )
+ sin ( radians(?) )
* sin( radians( IFNULL(a.latitude, 0) ) )
)) AS distance_in_miles
FROM
tab_provider a
INNER JOIN tab_provider_key b
ON a.provider_id = b.provider_id `
a.provider_id,
a.provider_uuid,
a.provider_internal_id,
a.provider_internal_id_suffix,
a.provider_muk_id,
a.organization_name,
a.gender,
a.accept_new_patients,
a.provider_name,
a.first_name,
a.last_name,
a.middle_name,
a.provider_title,
a.street_name1,
a.street_name2,
a.city_name,
a.state,
a.zipcode,
a.country,
a.latitude,
a.longitude,
a.phone_number,
a.create_at,
a.update_at,
a.active,
a.enabled,
a.created_user,
(3959 * acos (
cos ( radians(?) )
* cos( radians( a.latitude ) )
* cos( radians( a.longitude ) - radians(?) )
+ sin ( radians(?) )
* sin( radians( a.latitude ) )
)) AS distance_in_miles
FROM
tab_provider a
INNER JOIN tab_provider_key b
ON a.provider_id = b.provider_id `
}
func (c *providerRepo) GetAll(user entity.User) ([]entity.Provider, error) {
@@ -131,34 +131,6 @@ func (c *providerRepo) GetAll(user entity.User) ([]entity.Provider, error) {
return c.getKeys("", "", providers)
}
func (c *providerRepo) GetByUUID(providerUUID string, user entity.User) (entity.Provider, error) {
lat := 41.886406
long := -87.624225
query, where, err := c.getProfileQuery(user)
if err != nil {
return entity.Provider{}, err
}
query = c.getSelectQueryBase() + query + " WHERE a.provider_uuid = ? " + where
return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, providerUUID))
}
func (c *providerRepo) GetByID(providerID int64, user entity.User) (entity.Provider, error) {
lat := 41.886406
long := -87.624225
query, where, err := c.getProfileQuery(user)
if err != nil {
return entity.Provider{}, err
}
query = c.getSelectQueryBase() + query + " WHERE a.provider_id = ? " + where
return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, providerID))
}
func (c *providerRepo) GetByMukID(mukID string, user entity.User) (entity.Provider, error) {
lat := 41.886406
long := -87.624225
@@ -173,20 +145,6 @@ func (c *providerRepo) GetByMukID(mukID string, user entity.User) (entity.Provid
return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, mukID))
}
func (c *providerRepo) GetByNPI(NPI string, user entity.User) (entity.Provider, error) {
lat := 41.886406
long := -87.624225
query, where, err := c.getProfileQuery(user)
if err != nil {
return entity.Provider{}, err
}
query = c.getSelectQueryBase() + query + " WHERE a.provider_internal_id = ? " + where
return c.parseEntity(c.conn.QueryRow(query, lat, long, lat, NPI))
}
func (c *providerRepo) Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user entity.User) ([]entity.Provider, error) {
filter := " WHERE 1 = 1 "
params := make([]interface{}, 0)
@@ -335,11 +293,7 @@ func (c *providerRepo) parseEntity(row scanner) (retVal entity.Provider, err err
err = row.Scan(
&retVal.ProviderID, &retVal.ProviderUUID, &retVal.InternalID, &retVal.InternalSuffixID, &retVal.MukID, &retVal.OrganizatioName, &retVal.Gender, &retVal.AcceptNewPatients, &retVal.Name, &retVal.FirstName, &retVal.LastName, &retVal.MiddleName, &retVal.Title, &retVal.Address.StreetAddress1, &retVal.Address.StreetAddress2, &retVal.Address.CityName, &retVal.Address.State, &retVal.Address.ZipCode, &retVal.Address.Country, &retVal.Address.Latitude, &retVal.Address.Longitude, &retVal.Address.PhoneNumber, &retVal.CreateDate, &retVal.UpdateDate, &retVal.Active, &retVal.Enabled, &retVal.CreatedUser.ID, &retVal.Distance)
if err == sql.ErrNoRows {
return retVal, nil
} else {
return retVal, errors.Wrap(err)
}
return retVal, errors.Wrap(err)
}
func (c *providerRepo) Save(providers []entity.ProviderResponse, user entity.User) ([]entity.Provider, error) {

View File

@@ -29,7 +29,7 @@ func (c *rideRepo) getQuery() string {
b.user_id,
b.user_uuid,
b.name,
b.subscriber_id,
b.member,
c.ride_status_id,
c.ride_status,
c.key ride_status_key,
@@ -144,13 +144,13 @@ func (c *rideRepo) getProfileQuery(user entity.User) (query string, where string
switch p.Key {
case "AD", "BCBSIAD", "BDCAD", "PLANAD":
return
case "SP", "SPT", "VIRPT":
case "SP", "SPT":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa", "plan":
return
case "provider":
query = `INNER JOIN viw_visit_provider z ON a.ride_id = z.ride_id`
where = fmt.Sprintf(` AND (z.organization_uuid = '%s' OR z.parent_organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID)
query = `INNER JOIN viw_visit_provider o ON a.ride_id = o.ride_id`
where = fmt.Sprintf(` AND (o.organization_uuid = '%s' OR o.parent_organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID)
return
}
}
@@ -514,14 +514,14 @@ func (c *rideRepo) saveHeader(ride entity.Ride) (retVal entity.Ride, err error)
dataQuery = `SELECT
a.user_id user_id,
a.name,
a.subscriber_id,
a.member,
b.ride_status_id,
b.ride_status,
c.ride_type_id,
c.value ride_type,
d.user_id created_user_id,
d.name created_name,
IFNULL(d.subscriber_id, '') created_member,
IFNULL(d.member, '') created_member,
e.trip_type_id,
e.trip_type_key,
e.trip_type
@@ -676,7 +676,6 @@ func (c *rideRepo) GetByUUID(uuid string, user entity.User) (entity.Ride, error)
}
query = c.getQuery() + query + " WHERE a.ride_uuid = ? " + where
return c.parseEntity(c.conn.QueryRow(query, uuid))
}

View File

@@ -8,17 +8,14 @@ import (
)
type transaction struct {
tx *sql.Tx
users *userRepo
rides *rideRepo
visits *visitRepo
provider *providerRepo
notification *notificationRepo
profile *profileRepo
organization *organizationRepo
zipcodes *zipcodeRepo
plan *planRepo
passwordReset *passwordResetRepo
tx *sql.Tx
users *userRepo
rides *rideRepo
visits *visitRepo
provider *providerRepo
notification *notificationRepo
profile *profileRepo
organization *organizationRepo
}
func newTransaction(tx *sql.Tx) *transaction {
@@ -30,12 +27,6 @@ func newTransaction(tx *sql.Tx) *transaction {
t.rides = newRideRepo(tx)
t.visits = newVisitRepo(tx)
t.provider = newProviderRepo(tx)
t.notification = newNotificationRepo(tx)
t.profile = newProfileRepo(tx)
t.organization = newOrganizationRepo(tx)
t.zipcodes = newZipcodeRepo(tx)
t.plan = newPlanRepo(tx)
t.passwordReset = newPasswordResetRepo(tx)
return t
}
@@ -75,18 +66,6 @@ func (t transaction) Organization() contract.OrganizationRepo {
return t.organization
}
func (t transaction) Zipcodes() contract.ZipcodeRepo {
return t.zipcodes
}
func (t transaction) Plans() contract.PlanRepo {
return t.plan
}
func (t transaction) PasswordReset() contract.PasswordResetRepo {
return t.passwordReset
}
func (t *transaction) Commit() error {
err := t.tx.Commit()

View File

@@ -22,58 +22,6 @@ func newUserRepo(conn executor) *userRepo {
}
}
func (c *userRepo) GetByMemberID(memberID string) (entity.User, error) {
finalQuery := c.getQuery() + " AND a.subscriber_id = ? AND e.key = 'US'"
user, err := c.parseSet(c.conn.Query(finalQuery, memberID))
if err != nil {
return entity.User{}, err
}
if len(user) > 0 {
retVal := user[0]
retVal.Contacts, err = c.GetContacts(retVal.ID)
if err != nil {
return entity.User{}, err
}
retVal.Addresses = nil
retVal.Addresses, err = c.getAddressByUserID(retVal.ID)
if err != nil {
return entity.User{}, err
}
return retVal, nil
} else {
return entity.User{}, nil
}
}
func (c *userRepo) GetByEmail(email string) (entity.User, error) {
finalQuery := c.getQuery() + " AND b.email = ?"
user, err := c.parseSet(c.conn.Query(finalQuery, email))
if err != nil {
return entity.User{}, err
}
if len(user) > 0 {
retVal := user[0]
retVal.Contacts, err = c.GetContacts(retVal.ID)
if err != nil {
return entity.User{}, err
}
retVal.Addresses = nil
retVal.Addresses, err = c.getAddressByUserID(retVal.ID)
if err != nil {
return entity.User{}, err
}
return retVal, nil
} else {
return entity.User{}, nil
}
}
func (c *userRepo) GetByUUID(uuid string, profile string) (entity.User, error) {
params := make([]interface{}, 0)
params = append(params, uuid)
@@ -218,7 +166,7 @@ func (c *userRepo) parseEntity(row scanner) (retVal entity.User, err error) {
err = row.Scan(&retVal.ID, &retVal.UUID, &retVal.Name, &retVal.Member, &birthDate, &retVal.LoginID, &retVal.LoginUUID, &retVal.Email, &retVal.PhoneNumber, &retVal.LoginKey, &retVal.Gender, &retVal.Active, &retVal.Created, &retVal.Updated, &profile.ID, &profile.Name, &profile.Key, &profile.Active, &profile.Blocked, &profile.Suspended, &profile.Created, &profile.Updated, &profile.Organization.ID, &profile.Organization.UUID, &profile.Organization.Type.ID, &profile.Organization.Type.Name, &profile.Organization.Type.Key, &profile.Organization.Type.Description, &profile.Organization.Name, &profile.Organization.Description, &profile.Organization.ReferenceID, &profile.Organization.ParentID, &profile.Organization.Main,
&homeAddress.ID, &homeAddress.UUID, &homeAddress.AddressType.ID, &homeAddress.AddressType.Key, &homeAddress.AddressType.Name, &homeAddress.Name, &homeAddress.Address, &homeAddress.Latitude, &homeAddress.Longitude,
&workAddress.ID, &workAddress.UUID, &workAddress.AddressType.ID, &workAddress.AddressType.Key, &workAddress.AddressType.Name, &workAddress.Name, &workAddress.Address, &workAddress.Latitude, &workAddress.Longitude, &retVal.Type, &retVal.Test)
&workAddress.ID, &workAddress.UUID, &workAddress.AddressType.ID, &workAddress.AddressType.Key, &workAddress.AddressType.Name, &workAddress.Name, &workAddress.Address, &workAddress.Latitude, &workAddress.Longitude)
if err != nil {
if err != sql.ErrNoRows {
return retVal, errors.Wrap(err)
@@ -256,7 +204,7 @@ func (c *userRepo) getQuery() string {
a.user_id,
a.user_uuid,
a.name,
IFNULL(a.subscriber_id, '') subscriber_id,
IFNULL(a.member, '') member,
a.birth_date,
b.login_id,
b.login_uuid,
@@ -286,26 +234,24 @@ func (c *userRepo) getQuery() string {
IFNULL(f.organization_reference_id, 0) organization_reference_id,
IFNULL(f.organization_parent_id, 0) organization_parent_id,
(IFNULL(f.main_organization, b'0') = b'1') main_organization,
IFNULL(h.address_id, 0) home_address_id,
IFNULL(h.address_uuid, '') home_address_uuid,
IFNULL(h.address_type_id, 0) home_address_type_id,
IFNULL(h.address_type_key, '') home_address_type_key,
IFNULL(h.address_type_name, '') home_address_type_name,
IFNULL(h.name, '') home_name,
IFNULL(h.address, '') home_address,
IFNULL(h.lat, 0) home_lat,
IFNULL(h.long, 0) home_long,
IFNULL(i.address_id, 0) work_address_id,
IFNULL(i.address_uuid, '') work_address_uuid,
IFNULL(i.address_type_id, 0) work_address_type_id,
IFNULL(i.address_type_key, '') work_address_type_key,
IFNULL(i.address_type_name, '') work_address_type_name,
IFNULL(i.name, '') work_name,
IFNULL(i.address, '') work_address,
IFNULL(i.lat, 0) work_lat,
IFNULL(i.long, 0) work_long,
IFNULL(a.member_type, 'S') member_type,
user_test
IFNULL(h.address_id, 0) home_address_id,
IFNULL(h.address_uuid, '') home_address_uuid,
IFNULL(h.address_type_id, 0) home_address_type_id,
IFNULL(h.address_type_key, '') home_address_type_key,
IFNULL(h.address_type_name, '') home_address_type_name,
IFNULL(h.name, '') home_name,
IFNULL(h.address, '') home_address,
IFNULL(h.lat, 0) home_lat,
IFNULL(h.long, 0) home_long,
IFNULL(i.address_id, 0) work_address_id,
IFNULL(i.address_uuid, '') work_address_uuid,
IFNULL(i.address_type_id, 0) work_address_type_id,
IFNULL(i.address_type_key, '') work_address_type_key,
IFNULL(i.address_type_name, '') work_address_type_name,
IFNULL(i.name, '') work_name,
IFNULL(i.address, '') work_address,
IFNULL(i.lat, 0) work_lat,
IFNULL(i.long, 0) work_long
FROM
tab_user a
INNER JOIN
@@ -444,24 +390,6 @@ func (c *userRepo) SaveContact(contact entity.ContactInfo) (entity.ContactInfo,
return c.addContactInfo(contact)
}
func (c *userRepo) UpdateLogin(user entity.User) error {
const (
query = `UPDATE tab_login a
INNER JOIN tab_user b
ON a.user_id = b.user_id
SET a.email = ?,
a.phone_number = ?
WHERE
b.user_uuid = ?`
)
if _, err := c.conn.Exec(query, user.Email, user.PhoneNumber, user.UUID); err != nil {
return err
}
return nil
}
func (c *userRepo) RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error) {
const (
query = `DELETE FROM tab_contact WHERE contact_uuid = ?;`
@@ -549,7 +477,7 @@ func (c *userRepo) addProfileToUser(loginID int64, profileID int64, organization
func (c *userRepo) getUserByMember(u entity.User) (user entity.User, err error) {
user = u
users, err := c.parseSet(c.conn.Query(c.getQuery()+" AND a.active = 1 AND e.key = 'US' AND IFNULL(a.subscriber_id, '') = ?;", u.Member))
users, err := c.parseSet(c.conn.Query(c.getQuery()+" AND a.active = 1 AND e.key = 'US' AND IFNULL(a.member, '') = ?;", u.Member))
if err != nil {
return user, errors.Wrap(err)
}
@@ -614,11 +542,11 @@ func (c *userRepo) createLogin(user entity.User) (int64, string, error) {
func (c *userRepo) createUser(user entity.User) (int64, string, error) {
const (
query = "INSERT INTO tab_user(user_uuid, `name`, subscriber_id, birth_date, gender, member_type, user_hash, user_test) VALUES(?, ?, ?, ?, ?, ?, SHA2(CONCAT_WS('-',?,?,?,?,?), 512), ?) ON DUPLICATE KEY UPDATE user_uuid = ?, `name` = ?, subscriber_id = ?, birth_date = ?, gender = ?, user_test = ?;"
query = "INSERT INTO tab_user(user_uuid, `name`, member, birth_date, gender) VALUES(?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE user_uuid = ?, `name` = ?, member = ?, birth_date = ?, gender = ?;"
)
guid, _ := uuid.NewV4()
result, err := c.conn.Exec(query, guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender), user.Type, user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender), user.Type, user.Test, guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender), user.Test)
result, err := c.conn.Exec(query, guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender), guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender))
if err != nil {
return 0, "", err
}
@@ -633,7 +561,7 @@ func (c *userRepo) createUser(user entity.User) (int64, string, error) {
func (c *userRepo) RemoveAddress(addressUUID string) error {
const (
query = "UPDATE tab_address SET active = 0 WHERE address_uuid = ?;"
query = "UPDATE tab_address SET active = 0 WHERE address_uuid = ?"
)
_, err := c.conn.Exec(query, addressUUID)

View File

@@ -27,13 +27,14 @@ func (c *visitRepo) getProfileQuery(user entity.User) (query string, where strin
switch p.Key {
case "AD", "BCBSIAD", "BDCAD", "PLANAD":
return
case "SP", "SPT", "VIRPT":
case "SP", "SPT":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa", "plan":
return
case "provider":
query = ` INNER JOIN viw_visit_provider AS o ON o.visit_id = a.visit_id `
where = fmt.Sprintf(` AND ( o.organization_uuid = '%s' OR o.parent_organization_uuid = '%s' ) `, p.Organization.UUID, p.Organization.UUID)
query = ` INNER JOIN viw_visit_provider f
ON f.visit_id = a.visit_id `
where = fmt.Sprintf(` AND (f.organization_uuid = '%s' OR f.parent_organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID)
return
}
}
@@ -59,7 +60,7 @@ func (c *visitRepo) getQuery() string {
a.user_id,
c.user_uuid,
c.name user_name,
c.subscriber_id user_member,
c.member user_member,
c.birth_date user_birth_date,
c.gender user_gender,
a.visit_datetime,
@@ -78,23 +79,23 @@ func (c *visitRepo) getQuery() string {
IFNULL(a.pickup_id, '') visit_pickup_id,
IFNULL(a.pickup_address_id, 0) pickup_address_id,
IFNULL(a.address_id, 0) address_id,
IFNULL(a.provider_id, 0) provider_id,
IFNULL(a.provider_id, 0) provider_id,
IFNULL(f.provider_uuid, '') provider_uuid,
IFNULL(f.provider_internal_id, '') provider_internal_id,
IFNULL(f.provider_muk_id, '') provider_muk_id,
IFNULL(f.provider_name, '') provider_name
FROM
tab_visit AS a
INNER JOIN tab_visit_status AS b
tab_visit a
INNER JOIN tab_visit_status b
ON a.visit_status_id = b.visit_status_id
INNER JOIN tab_user AS c
INNER JOIN tab_user c
ON c.user_id = a.user_id
INNER JOIN tab_user AS d
INNER JOIN tab_user d
ON d.user_id = a.created_user_id
INNER JOIN tab_trip_type AS e
INNER JOIN tab_trip_type e
ON e.trip_type_id = a.trip_type_id
INNER JOIN tab_provider AS f
ON f.provider_id = a.provider_id `
INNER JOIN tab_provider f
ON f.provider_id = a.provider_id `
}
func (c *visitRepo) GetAll(user entity.User) ([]entity.Visit, error) {
@@ -190,13 +191,12 @@ func (c *visitRepo) Create(visit entity.Visit) (entity.Visit, error) {
row := c.conn.QueryRow(statusQuery, retVal.Status.Key, retVal.User.UUID, retVal.CreatedUser.UUID, retVal.TripType.Key)
if err := row.Scan(&retVal.Status.ID, &retVal.Status.Key, &retVal.Status.Value, &retVal.User.ID, &retVal.User.Name, &retVal.CreatedUser.ID, &retVal.CreatedUser.Name, &retVal.TripType.ID, &retVal.TripType.Key, &retVal.TripType.Value); err != nil {
fmt.Println("data.Visit: Error getting base data: ", err.Error())
fmt.Println("Error to get base data: ", err.Error())
return retVal, err
}
results, err := c.conn.Exec(query, retVal.UUID, retVal.Status.ID, retVal.User.ID, retVal.VisitDatetime, retVal.PickupDatetime, retVal.Notes, retVal.CreatedUser.ID, toNullInt64(retVal.VisitDuration), retVal.ExternalID, returnDate, retVal.TripType.ID, retVal.Pickup.ID, retVal.PickupAddressID, retVal.DestinationAddressID, retVal.Provider.ProviderID)
if err != nil {
fmt.Println("data.Visit: Error inserting visit: ", err.Error())
return retVal, err
}
@@ -205,5 +205,6 @@ func (c *visitRepo) Create(visit entity.Visit) (entity.Visit, error) {
return retVal, err
}
fmt.Println("Visit ID: ", retVal.ID)
return retVal, nil
}

View File

@@ -1,65 +0,0 @@
package datamysql
import (
"database/sql"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
// rideRepo maps methods to database
type zipcodeRepo struct {
conn executor
}
func newZipcodeRepo(conn executor) *zipcodeRepo {
return &zipcodeRepo{
conn: conn,
}
}
func (c *zipcodeRepo) getQuery() string {
const (
query = `SELECT
a.participating_zip_code_id,
a.participating_zip_code_uuid,
a.zipcode,
(IFNULL(a.participating, b'0') = b'1') participating
FROM
tab_participating_zip_code a `
)
return query
}
// parseSet parses a result set result to an entity array
func (c *zipcodeRepo) parseSet(rows *sql.Rows, err error) ([]entity.Zipcode, error) {
if err != nil {
return nil, errors.Wrap(err)
}
result := make([]entity.Zipcode, 0)
for rows.Next() {
entity, err := c.parseEntity(rows)
if err != nil {
return nil, errors.Wrap(err)
}
result = append(result, entity)
}
return result, nil
}
// parseEntity parses a result to an entity
func (c *zipcodeRepo) parseEntity(row scanner) (retVal entity.Zipcode, err error) {
err = row.Scan(
&retVal.ID, &retVal.UUID, &retVal.Zipcode, &retVal.Participating)
return retVal, errors.Wrap(err)
}
func (c *zipcodeRepo) GetAll() ([]entity.Zipcode, error) {
return c.parseSet(c.conn.Query(c.getQuery()))
}
func (c *zipcodeRepo) GetByParticipatingZipcode(zipcode string) (entity.Zipcode, error) {
return c.parseEntity(c.conn.QueryRow(c.getQuery()+"WHERE a.participating = 1 AND a.zipcode = ?", zipcode))
}

View File

@@ -1,22 +0,0 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443;
ssl on;
ssl_certificate /opt/app/certs/ssl_certificate.cer;
ssl_certificate_key /opt/app/certs/private.key;
server_name portal-api.dev.bcbsinstitute.com;
server_tokens off;
location / {
proxy_pass http://127.0.0.1:5100;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

View File

@@ -1,22 +0,0 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443;
ssl on;
ssl_certificate /opt/app/certs/ssl_certificate.cer;
ssl_certificate_key /opt/app/certs/private.key;
server_name portal-api.bcbsinstitute.com;
server_tokens off;
location / {
proxy_pass http://127.0.0.1:5100;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

View File

@@ -1,22 +0,0 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443;
ssl on;
ssl_certificate /opt/app/certs/ssl_certificate.cer;
ssl_certificate_key /opt/app/certs/private.key;
server_name portal-api.dev.bcbsinstitute.com;
server_tokens off;
location / {
proxy_pass http://127.0.0.1:5100;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

View File

@@ -12,9 +12,6 @@ type repoManager interface {
Notification() NotificationRepo
Profile() ProfileRepo
Organization() OrganizationRepo
Zipcodes() ZipcodeRepo
Plans() PlanRepo
PasswordReset() PasswordResetRepo
}
// UserRepo defines the data set for users
@@ -22,8 +19,6 @@ type UserRepo interface {
GetAll() (list []entity.User, err error)
GetByID(userID int64) (retVal entity.User, err error)
GetByUUID(uuid string, profile string) (entity.User, error)
GetByMemberID(memberID string) (entity.User, error)
GetByEmail(email string) (entity.User, error)
Login(email string, pass string) (entity.User, error)
FullLogin(loginType string, key string, pass string, profile string) (entity.User, error)
Create(user entity.User) (entity.User, error)
@@ -34,7 +29,6 @@ type UserRepo interface {
RemoveAddress(addressUUID string) error
SaveContact(contact entity.ContactInfo) (entity.ContactInfo, error)
RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error)
UpdateLogin(user entity.User) error
}
// RideRepo defines the data set for Rides
@@ -62,9 +56,6 @@ type ProviderRepo interface {
GetAll(user entity.User) ([]entity.Provider, error)
Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user entity.User) ([]entity.Provider, error)
GetByMukID(mukID string, user entity.User) (entity.Provider, error)
GetByUUID(providerUUID string, user entity.User) (entity.Provider, error)
GetByNPI(NPI string, user entity.User) (entity.Provider, error)
GetByID(providerID int64, user entity.User) (entity.Provider, error)
}
// NotificationRepo defines the data set for Notification
@@ -81,7 +72,6 @@ type OrganizationRepo interface {
GetAllTypes() ([]entity.OrganizationType, error)
GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error)
GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error)
GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error)
GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error)
GetContactsByOrganizationID(organizationID int64) ([]entity.OrganizationContact, error)
GetContactsByUUID(contactUUID string) (entity.OrganizationContact, error)
@@ -100,13 +90,6 @@ type OrganizationRepo interface {
GetTypeByKey(key string) (entity.OrganizationType, error)
}
type PlanRepo interface {
GetByAlphaPrefix(alphaPrefix string) (entity.Plan, error)
GetByUUID(planUUID string) ([]entity.Plan, error)
GetByID(planID int64) ([]entity.Plan, error)
GetByPrefixUUID(prefixUUID string) (entity.Plan, error)
}
// VisitRepo defines the data set for Rides
type VisitRepo interface {
Create(visit entity.Visit) (entity.Visit, error)
@@ -121,17 +104,3 @@ type ProfileRepo interface {
GetVisibles(visible bool) ([]entity.Profile, error)
GetByOrganizationType(organizationTypeID int64) ([]entity.Profile, error)
}
type ZipcodeRepo interface {
GetAll() ([]entity.Zipcode, error)
GetByParticipatingZipcode(zipcode string) (entity.Zipcode, error)
}
type PasswordResetRepo interface {
GetAll() ([]entity.PasswordReset, error)
CreatePasswordResetEntry(passwordResetEntry entity.PasswordReset) (entity.PasswordReset, error)
GetByID(ID int64) (entity.PasswordReset, error)
GetByToken(token string) (entity.PasswordReset, error)
SetTokenOpened(token string) error
SetTokenUsed(token string) error
}

View File

@@ -1,14 +0,0 @@
package entity
import "time"
type PasswordReset struct {
ID int64 `db:"password_reset_id" json:"-"`
UUID string `db:"password_reset_uuid" json:"uuid"`
User User `db:"-" json:"user"`
Token string `db:"token" json:"token"`
Created time.Time `db:"create_date" json:"create_date"`
Expires time.Time `db:"expire_date" json:"expire_date"`
Used bool `db:"used" json:"used"`
Opened bool `db:"opend" json:"opened"`
}

View File

@@ -1,21 +0,0 @@
package entity
import "time"
type Plan struct {
ID int64 `json:"-"`
UUID string `json:"id"`
Name string `json:"name"`
InternalID string `json:"key"`
Status bool `json:"desc"`
PlanEntityID int64 `json:"plan_entity_id"`
EntityID int64 `json:"entity_id"`
PayerID int64 `json:"payer_id"`
PayerName string `json:"payer_name"`
PrefixID int64 `json:"prefix_id"`
PrefixUUID string `json:"prefix_uuid"`
AlphaPrefix string `json:"alpha_prefix"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
Active bool `json:"active"`
}

View File

@@ -26,7 +26,6 @@ type Provider struct {
Keys []ProviderKey `json:"keys"`
Address ProviderAddress `json:"address"`
Distance float64 `json:"distance"`
Organization Organization `json:"organization"`
}
type ProviderKey struct {

View File

@@ -30,8 +30,6 @@ type User struct {
Profiles []Profile `json:"profiles,omitempty"`
Types []OrganizationType `json:"types,omitempty"`
Organizations []Organization `json:"organizations,omitempty"`
Type string `json:"type,omitempty"`
Test bool `json:"test,omitempty"`
}
type ContactInfo struct {

View File

@@ -1,8 +0,0 @@
package entity
type Zipcode struct {
ID int64 `db:"participating_zip_code_id" json:"-"`
UUID string `db:"participating_zip_code_uuid" json:"uuid"`
Zipcode string `db:"zipcode" json:"zipcode"`
Participating bool `db:"participating" json:"participating"`
}

View File

@@ -28,10 +28,6 @@ func (s *organizationService) GetByName(name string, searchType string, user ent
return s.svc.db.Organization().GetByName(name, searchType, user)
}
func (s *organizationService) GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error) {
return s.svc.db.Organization().GetByTypeAndReferenceID(typeKey, referenceID, user)
}
func (s *organizationService) GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) {
organization, err := s.svc.db.Organization().GetByUUID(organizationUUID, user)
if err != nil {

View File

@@ -1,41 +0,0 @@
package service
import (
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
// userService is the domain service for user operations
type passwordResetService struct {
svc *Service
}
// newUserService returns an instance of userService
func newPasswordResetService(svc *Service) *passwordResetService {
return &passwordResetService{
svc: svc,
}
}
func (s *passwordResetService) GetAll() ([]entity.PasswordReset, error) {
return s.svc.db.PasswordReset().GetAll()
}
func (s *passwordResetService) GetByID(ID int64) (entity.PasswordReset, error) {
return s.svc.db.PasswordReset().GetByID(ID)
}
func (s *passwordResetService) GetByToken(token string) (entity.PasswordReset, error) {
return s.svc.db.PasswordReset().GetByToken(token)
}
func (s *passwordResetService) CreatePasswordResetEntry(passwordResetEntry entity.PasswordReset) (entity.PasswordReset, error) {
return s.svc.db.PasswordReset().CreatePasswordResetEntry(passwordResetEntry)
}
func (s *passwordResetService) SetTokenOpened(token string) error {
return s.svc.db.PasswordReset().SetTokenOpened(token)
}
func (s *passwordResetService) SetTokenUsed(token string) error {
return s.svc.db.PasswordReset().SetTokenUsed(token)
}

View File

@@ -1,31 +0,0 @@
package service
import (
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
type planService struct {
svc *Service
}
func newPlanService(svc *Service) *planService {
return &planService{
svc: svc,
}
}
func (s *planService) GetByAlphaPrefix(alphaPrefix string) (entity.Plan, error) {
return s.svc.db.Plans().GetByAlphaPrefix(alphaPrefix)
}
func (s *planService) GetByUUID(planUUID string) ([]entity.Plan, error) {
return s.svc.db.Plans().GetByUUID(planUUID)
}
func (s *planService) GetByID(planID int64) ([]entity.Plan, error) {
return s.svc.db.Plans().GetByID(planID)
}
func (s *planService) GetByPrefixUUID(prefixUUID string) (entity.Plan, error) {
return s.svc.db.Plans().GetByPrefixUUID(prefixUUID)
}

View File

@@ -1,9 +1,6 @@
package service
import (
"errors"
"fmt"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
@@ -45,68 +42,5 @@ func (s *providerService) Get(query string, lat float64, long float64, distance
}
func (s *providerService) GetByMukID(mukID string, user entity.User) (entity.Provider, error) {
provider, err := s.svc.db.Provider().GetByMukID(mukID, user)
if err != nil {
return provider, err
}
organization, err := s.svc.db.Organization().GetByTypeAndReferenceID("provider", provider.ProviderID, user)
if err != nil {
return provider, err
}
provider.Organization = organization
return provider, nil
}
func (s *providerService) GetByUUID(providerUUID string, user entity.User) (entity.Provider, error) {
provider, err := s.svc.db.Provider().GetByUUID(providerUUID, user)
if err != nil {
fmt.Println("providerService.GetByUUID: Provider UUID: ", providerUUID)
fmt.Println("providerService.GetByUUID: Provider Error: ", err.Error())
return provider, err
}
organization, err := s.svc.db.Organization().GetByTypeAndReferenceID("provider", provider.ProviderID, user)
if err != nil {
fmt.Println("providerService.GetByUUID: OrganizationByType ProviderID : ", provider.ProviderID)
fmt.Println("providerService.GetByUUID: OrganizationByType Error: ", err.Error())
return provider, err
}
provider.Organization = organization
return provider, nil
}
func (s *providerService) GetByNPI(NPI string, user entity.User) (entity.Provider, error) {
provider, err := s.svc.db.Provider().GetByNPI(NPI, user)
if err != nil {
return provider, err
}
organization, err := s.svc.db.Organization().GetByTypeAndReferenceID("provider", provider.ProviderID, user)
if err != nil {
return provider, err
}
provider.Organization = organization
return provider, nil
}
func (s *providerService) GetByOrganization(organizationUUID string, user entity.User) (entity.Provider, error) {
organization, err := s.svc.db.Organization().GetByUUID(organizationUUID, user)
if err != nil {
return entity.Provider{}, err
}
if organization.Type.Key != "provider" {
return entity.Provider{}, errors.New("invalid organization")
}
provider, err := s.svc.db.Provider().GetByID(organization.ReferenceID, user)
if err != nil {
return entity.Provider{}, err
}
return provider, nil
return s.svc.db.Provider().GetByMukID(mukID, user)
}

View File

@@ -1,8 +1,6 @@
package service
import (
"fmt"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
@@ -22,13 +20,11 @@ func newRideService(svc *Service) *rideService {
func (s *rideService) Save(ride entity.Ride) (entity.Ride, error) {
ride, err := s.svc.db.Rides().Save(ride)
if err != nil {
fmt.Println("Ride Service.Save: Error saving Ride: ", err.Error())
return ride, err
}
user, err := s.svc.db.Users().GetByID(ride.CreatedUser.ID)
if err != nil {
fmt.Println("Ride Service.Save: Error getting User: ", err.Error())
return ride, err
}
@@ -60,14 +56,7 @@ func (s *rideService) GetByID(id int64, user entity.User) (entity.Ride, error) {
// GetByUUID return a specific ride
func (s *rideService) GetByUUID(uuid string, user entity.User) (entity.Ride, error) {
ride, err := s.svc.db.Rides().GetByUUID(uuid, user)
if err != nil {
fmt.Println("Ride Service.GetByUUID: Ride UUID: ", uuid)
fmt.Println("Ride Service.GetByUUID: Error getting Ride: ", err.Error())
return entity.Ride{}, err
}
return ride, nil
return s.svc.db.Rides().GetByUUID(uuid, user)
}
// GetByUUID return a specific ride

View File

@@ -15,19 +15,16 @@ var (
// Service holds the domain service repositories
type Service struct {
db contract.DataManager
cache contract.CacheManager
tnc contract.TNCManager
Users *userService
Rides *rideService
Visits *visitService
Provider *providerService
Notification *notificationService
Profile *profileService
Organization *organizationService
Zipcodes *zipcodeService
Plans *planService
PasswordReset *passwordResetService
db contract.DataManager
cache contract.CacheManager
tnc contract.TNCManager
Users *userService
Rides *rideService
Visits *visitService
Provider *providerService
Notification *notificationService
Profile *profileService
Organization *organizationService
}
// New returns a new domain Service instance
@@ -42,9 +39,6 @@ func New(db contract.DataManager, cache contract.CacheManager, cfg *config.Confi
instance.Notification = newNotificationService(instance)
instance.Profile = newProfileService(instance)
instance.Organization = newOrganizationService(instance)
instance.Zipcodes = newZipcodeService(instance)
instance.Plans = newPlanService(instance)
instance.PasswordReset = newPasswordResetService(instance)
})
return instance, nil

View File

@@ -33,14 +33,6 @@ func (s *userService) GetByUUID(uuid string, profile string) (entity.User, error
return s.svc.db.Users().GetByUUID(uuid, profile)
}
func (s *userService) GetByMemberID(memberID string) (entity.User, error) {
return s.svc.db.Users().GetByMemberID(memberID)
}
func (s *userService) GetByEmail(email string) (entity.User, error) {
return s.svc.db.Users().GetByEmail(email)
}
// Login returns a specific user by email and pass
func (s *userService) Login(email string, pass string) (entity.User, error) {
return s.svc.db.Users().Login(email, pass)
@@ -76,10 +68,6 @@ func (s *userService) CreateBulk(users []entity.User) ([]entity.User, error) {
return users, nil
}
func (s *userService) UpdateLogin(user entity.User) error {
return s.svc.db.Users().UpdateLogin(user)
}
// GetUsersByProfile returns a list of users by profile
func (s *userService) GetUsersByProfile(profile string) ([]entity.User, error) {
return s.svc.db.Users().GetUsersByProfile(profile)

View File

@@ -29,10 +29,10 @@ func (s *visitService) GetAll(user entity.User) ([]entity.Visit, error) {
return nil, err
}
rides, _ := s.svc.db.Rides().GetAll(user)
// if err != nil {
// return nil, err
// }
rides, err := s.svc.db.Rides().GetAll(user)
if err != nil {
return nil, err
}
ridesByVisit := make(map[int64][]entity.Ride)
for _, r := range rides {
@@ -55,10 +55,10 @@ func (s *visitService) GetByUUID(visitUUID string, user entity.User) (entity.Vis
return entity.Visit{}, errors.Wrap(err)
}
rides, _ := s.svc.db.Rides().GetByVisitUUID(visitUUID, user)
// if err != nil {
// return entity.Visit{}, errors.Wrap(err)
// }
rides, err := s.svc.db.Rides().GetByVisitUUID(visitUUID, user)
if err != nil {
return entity.Visit{}, errors.Wrap(err)
}
visit.Rides = rides
return visit, nil
@@ -71,10 +71,10 @@ func (s *visitService) GetByID(visitID int64, user entity.User) (entity.Visit, e
return entity.Visit{}, errors.Wrap(err)
}
rides, _ := s.svc.db.Rides().GetByVisitUUID(visit.UUID, user)
// if err != nil {
// return entity.Visit{}, errors.Wrap(err)
// }
rides, err := s.svc.db.Rides().GetByVisitUUID(visit.UUID, user)
if err != nil {
return entity.Visit{}, errors.Wrap(err)
}
visit.Rides = rides
return visit, nil

View File

@@ -1,25 +0,0 @@
package service
import (
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
// userService is the domain service for user operations
type zipcodeService struct {
svc *Service
}
// newUserService returns an instance of userService
func newZipcodeService(svc *Service) *zipcodeService {
return &zipcodeService{
svc: svc,
}
}
func (s *zipcodeService) GetAll() ([]entity.Zipcode, error) {
return s.svc.db.Zipcodes().GetAll()
}
func (s *zipcodeService) GetByParticipatingZipcode(zipcode string) (entity.Zipcode, error) {
return s.svc.db.Zipcodes().GetByParticipatingZipcode(zipcode)
}

View File

@@ -1,26 +1,35 @@
{
"containerDefinitions": [
{
"name": "portal-api",
"image": "105690980714.dkr.ecr.us-east-2.amazonaws.com/nemt-portal-api:dev",
"name": "api-development",
"image": "xxxxxxxxxxx.dkr.ecr.us-east-1.amazonaws.com/dev.nemt-portal-api:latest",
"cpu": 128,
"memory": 128,
"essential": true,
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "portal-api",
"awslogs-region": "us-east-2",
"awslogs-stream-prefix": "test"
"awslogs-group": "nemt-portal-api",
"awslogs-region": "sa-east-1",
"awslogs-stream-prefix": "development"
}
},
"portMappings": [
{
"containerPort": 443,
"hostPort": 5100
"containerPort": 5100
}
],
"environment": [
{
"name": "SERVICE_5100_NAME",
"value": "portal-api"
},
{
"name": "SERVICE_5100_TAG",
"value": "api"
}
]
}
],
"family": "portal-api-dev"
"family": "api-development"
}

View File

@@ -16,7 +16,7 @@
},
"portMappings": [
{
"containerPort": 443,
"containerPort": 5100,
"hostPort": 5100
}
]

View File

@@ -16,7 +16,7 @@
},
"portMappings": [
{
"containerPort": 443,
"containerPort": 5100,
"hostPort": 5100
}
]

View File

@@ -25,15 +25,13 @@ type Config struct {
Blue365 Blue365Config
Email EmailConfig
GoogleShortener GoogleShortenerConfig
Eligibility EligibilityConfig
}
// AppConfig represents the configuration values about the application.
type AppConfig struct {
Name string
Debug bool
Docs DocsConfig
DisableZipValidation bool
Name string
Debug bool
Docs DocsConfig
}
// TwilioConfig represents the configuration values about the twilio.
@@ -139,10 +137,6 @@ type GoogleShortenerConfig struct {
SecretKey string
}
type EligibilityConfig struct {
Url string
}
// Read returns the configuration values,
// based on the configuration files and environment variables.
func Read() (*Config, error) {
@@ -161,9 +155,8 @@ func Read() (*Config, error) {
return &Config{
App: AppConfig{
Name: viper.GetString("app.name"),
Debug: viper.GetBool("app.debug"),
DisableZipValidation: viper.GetBool("app.disable-zip-validation"),
Name: viper.GetString("app.name"),
Debug: viper.GetBool("app.debug"),
Docs: DocsConfig{
YAMLPath: viper.GetString("app.docs.yaml-path"),
SwaggerPath: viper.GetString("app.docs.swagger-path"),
@@ -245,9 +238,6 @@ func Read() (*Config, error) {
ClientID: viper.GetString("google-shortener.client-id"),
SecretKey: viper.GetString("google-shortener.secret-key"),
},
Eligibility: EligibilityConfig{
Url: viper.GetString("eligibility.url"),
},
}, nil
}

View File

@@ -1,32 +0,0 @@
user nginx;
worker_processes 1;
daemon on;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}

View File

@@ -73,4 +73,4 @@ func CanCreateOrganization(user viewmodel.User, organization viewmodel.Organizat
func CanUpdateOrganization(user viewmodel.User, organization viewmodel.Organization) bool{
return CanCreateOrganization(user, organization)
}
}

View File

@@ -1,15 +1,15 @@
package eligibilityroute
import (
"encoding/xml"
"fmt"
"math/rand"
"html"
"strings"
"sync"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
"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"
"github.com/labstack/echo"
@@ -37,29 +37,6 @@ func controllerInstance(cfg *config.Config, svc *applicationservice.Service) *co
return instance
}
func (c *controller) rangeIn(low, hi int) string {
result := low + rand.Intn(hi-low)
return fmt.Sprintf("%v", result)
}
func (c *controller) generatePassword(n int) string {
const (
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
return c.stringWithCharset(n, charset)
}
func (c *controller) stringWithCharset(length int, charset string) string {
b := make([]byte, length)
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}
func (c *controller) handleEligibility(ctx echo.Context) error {
var eligibility viewmodel.Eligibility
@@ -67,58 +44,24 @@ func (c *controller) handleEligibility(ctx echo.Context) error {
return routeutils.HandleAPIError(ctx, err)
}
authUser, err := auth.GetUserDetail(ctx, c.cfg)
ret, err := c.bcbsi.BXE.CheckEligibility(eligibility)
if err != nil {
fmt.Println("Error Here: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
var provider viewmodel.ProviderResp
provider, err = c.svc.Provider.GetByNPI(eligibility.RawProvider.FivePartKeyGroups[0].ProviderNum, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if ret.QueryResult.HIPPA271.T271 != "" {
xmlString := html.UnescapeString(ret.QueryResult.HIPPA271.T271)
xmlReader := strings.NewReader(xmlString)
if provider.ProviderUUID == "" {
org := viewmodel.Organization{
Type: viewmodel.OrganizationType{
Key: "provider",
Name: "Provider",
},
Name: eligibility.RawProvider.OrgName,
Description: eligibility.RawProvider.OrgName,
Main: false,
Author: authUser,
LastEditor: authUser,
Reference: eligibility.RawProvider,
}
org, err = c.svc.Organization.AddOrganization(org, authUser)
var f viewmodel.Interchange271
err = xml.NewDecoder(xmlReader).Decode(&f)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
fmt.Println("Error to unmarshal: ", err.Error())
}
provider, err = c.svc.Provider.GetByOrganization(org.UUID, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
}
user, err := c.svc.Users.CheckAndCreateMember(eligibility.User, provider, authUser)
if err != nil {
if validationError, ok := err.(*viewmodel.ValidationError); ok {
if len(validationError.Errors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, validationError.Message, validationError.Errors)
} else {
return routeutils.ResponseAPIServiceError(ctx, validationError.Message)
}
} else {
return routeutils.HandleAPIError(ctx, err)
}
}
if authUser.Profiles[0].Key == "VIRPT" {
return ctx.JSON(204, nil)
return ctx.JSON(200, f)
} else {
return ctx.JSON(200, user)
return routeutils.ResponseAPIOK(ctx, ret)
}
}

View File

@@ -63,17 +63,12 @@ func (c *controller) handleCancel(ctx echo.Context) error {
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 ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
if err = c.tnc.Lyft.CancelRide(lyftRide); err != nil {
if err.Error() != "ride_not_found" {
fmt.Println("Error to cancel with Lyft: ", err.Error())
@@ -149,18 +144,13 @@ func (c *controller) handle(ctx echo.Context) 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 {
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 {
@@ -246,7 +236,7 @@ func (c *controller) handleReady(ctx echo.Context) error {
}
var lyftRide viewmodel.RideRequest
if authUser.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
} else {
fmt.Println("In Production")
@@ -268,7 +258,7 @@ func (c *controller) handleReady(ctx echo.Context) error {
lyftRide.Passenger.PhoneNumber = *nextRide.User.PhoneNumber
lyftRide.RideType = "lyft"
if authUser.Test {
if c.cfg.LyftProd.UserUUID != nextRide.CreatedUser.ID {
lyftRide, err = c.tnc.Lyft.RequestRide(lyftRide)
} else {
fmt.Println("In Production")

View File

@@ -57,14 +57,8 @@ func (c *controller) handleStateChange(ctx echo.Context) 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 lyftRide viewmodel.RideRequest
if authUser.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
_, err = c.tnc.Lyft.GetRideStatus(viewmodel.RideRequest{RideID: ride.InternalID}, status)
go func() {
secondCall := func() {

View File

@@ -1,151 +0,0 @@
package passwordresetroute
import (
"crypto/sha256"
"fmt"
"math/rand"
"strings"
"sync"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"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"
)
const (
tokenExpirationTime = 90 // in minutes
randomStringLength = 15
baseURL = "http://localhost:5000"
passwordResetEmailSubject = "Reset Your Password"
passwordResetEmailMainBody = "To reset your password click here or copy the following link and paste it into your browser: \n\n " + baseURL + "/#/reset-password/"
passwordResetEmailFooter = "\nThis link expires in 90 minutes"
)
var (
instance *controller
once sync.Once
)
type controller struct {
svc *applicationservice.Service
cfg *config.Config
}
func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *controller {
once.Do(func() {
instance = &controller{
svc: svc,
cfg: cfg,
}
rand.Seed(time.Now().UTC().UnixNano())
})
return instance
}
func (c *controller) handleResetRequest(ctx echo.Context) error {
userEmail, err := routeutils.GetAndValidateStringParam(ctx, "email", "mandatory field")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
//find if user with email exists
user, err := c.svc.Users.GetByEmail(userEmail)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if user.Email == nil || (*user.Email != userEmail) {
return routeutils.ResponseAPIOK(ctx, nil) //more secure, don't inform user (attacker) that email doesn't exists
}
//create and store reset token
timeNow := time.Now()
expirationTime := timeNow.Add(time.Minute * tokenExpirationTime)
randomArray := make([]byte, randomStringLength)
rand.Read(randomArray)
token := fmt.Sprintf("%x", sha256.Sum256(randomArray))
passwordResetEntry := viewmodel.PasswordReset{
User: user,
Token: token,
Expires: expirationTime,
Opened: false,
Used: false,
}
_, err = c.svc.PasswordReset.CreatePasswordResetEntry(passwordResetEntry)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
//Send email with reset link
notification := viewmodel.Notification{
Type: applicationservice.NotificationTypeEmail,
From: c.cfg.Email.Sender,
To: "test.test.no@yandex.com",
Subject: passwordResetEmailSubject,
Message: passwordResetEmailMainBody + token + passwordResetEmailFooter,
}
notification, err = c.svc.Notification.SendNotificationWithoutWritingToDatabase(notification)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
return routeutils.ResponseAPIOK(ctx, nil)
}
func (c *controller) handleResetComplete(ctx echo.Context) error {
userToken, err := routeutils.GetAndValidateStringParam(ctx, "token", "mandatory field")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
var user viewmodel.User
if err = ctx.Bind(&user); err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if len(strings.TrimSpace(user.Pass)) < 1 {
routeutils.ResponseAPIPasswordResetFailed(ctx, "No password")
}
passwordResetEntry, err := c.svc.PasswordReset.GetByToken(userToken)
if err != nil || len(passwordResetEntry.Token) < 1 || passwordResetEntry.Expires.Before(time.Now()) || passwordResetEntry.Used == true {
routeutils.ResponseAPIPasswordResetFailed(ctx, "Token error")
}
fullUserData, err := c.svc.Users.GetByUUID(passwordResetEntry.User.ID, "")
if err != nil {
routeutils.ResponseAPIPasswordResetFailed(ctx, "User problem")
}
fmt.Println(fullUserData)
//write new password in database
if err := c.svc.PasswordReset.SetTokenUsed(userToken); err != nil {
routeutils.ResponseAPIPasswordResetFailed(ctx, "Reset failed")
}
return routeutils.ResponseAPIOK(ctx, nil)
}
func (c *controller) handleTokenOpen(ctx echo.Context) error {
token, err := routeutils.GetAndValidateStringParam(ctx, "token", "mandatory field")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if err := c.svc.PasswordReset.SetTokenOpened(token); err != nil {
return routeutils.HandleAPIError(ctx, err)
}
return routeutils.ResponseAPIOK(ctx, nil)
}

View File

@@ -1,21 +0,0 @@
package passwordresetroute
import (
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"github.com/labstack/echo"
)
const (
resetRequest = "/request/:email"
resetComplete = "/complete/:token"
tokenOpen = "/open/:token"
)
func Register(r *echo.Group, cfg *config.Config, svc *applicationservice.Service) {
ctrl := controllerInstance(svc, cfg)
r.POST(resetRequest, ctrl.handleResetRequest)
r.POST(resetComplete, ctrl.handleResetComplete)
r.POST(tokenOpen, ctrl.handleTokenOpen)
}

View File

@@ -124,27 +124,27 @@ func (c *controller) handleList(ctx echo.Context) error {
name := ctx.QueryParam("name")
searchBy := ctx.QueryParam("searchBy")
lat, err := routeutils.GetAndValidateFloatQueryParam(ctx, "lat", "latitude is required")
if err != nil {
return err
}
// lat, err := routeutils.GetAndValidateFloatQueryParam(ctx, "lat", "latitude is mandatory")
// if err != nil {
// return err
// }
long, err := routeutils.GetAndValidateFloatQueryParam(ctx, "long", "longitude is required")
if err != nil {
return err
}
// long, err := routeutils.GetAndValidateFloatQueryParam(ctx, "long", "longitude is mandatory")
// if err != nil {
// return err
// }
distance, err := routeutils.GetAndValidateIntQueryParam(ctx, "distance", "distance is required")
distance, err := routeutils.GetAndValidateIntQueryParam(ctx, "distance", "distance is mandatory")
if err != nil {
distance = 10
}
limit, err := routeutils.GetAndValidateIntQueryParam(ctx, "limit", "limit is required")
limit, err := routeutils.GetAndValidateIntQueryParam(ctx, "limit", "limit is mandatory")
if err != nil {
limit = 50
}
sortBy, err := routeutils.GetAndValidateStringQueryParam(ctx, "sortby", "limit is required")
sortBy, err := routeutils.GetAndValidateStringQueryParam(ctx, "sortby", "limit is mandatory")
if err != nil || (sortBy != "distance" && sortBy != "name") {
sortBy = "distance"
}
@@ -152,8 +152,8 @@ func (c *controller) handleList(ctx echo.Context) error {
providerParams := npdmodel.ProviderSearchParams{
Name: name,
SearchBy: searchBy,
Latitude: lat,
Longitude: long,
Latitude: 41.819078,
Longitude: -87.623129,
Distance: distance,
Limit: limit,
Offset: 0,

View File

@@ -13,11 +13,9 @@ import (
"bitbucket.org/nemt/nemt-portal-api/server/router/lyfthookroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/notificationroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/organizationroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/passwordresetroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/placesroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/profileroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/providerroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/selfregisterroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/tncroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/twilioroute"
"bitbucket.org/nemt/nemt-portal-api/server/router/usersroute"
@@ -39,17 +37,14 @@ func Register(e *echo.Echo, cfg *config.Config, svc *applicationservice.Service,
lyfthookroute.Register(prefixGroup.Group("/lyfthook"), cfg, svc, tnc, notification)
externalroute.Register(prefixGroup.Group("/ext"), cfg, svc, tnc, notification)
authenticateroute.Register(prefixGroup.Group("/authenticate"), cfg, svc)
selfregisterroute.Register(prefixGroup.Group("/selfregister"), cfg, svc)
passwordresetroute.Register(prefixGroup.Group("/passwordreset"), cfg, svc)
appGroup := prefixGroup.Group("/" + cfg.App.Name)
usersroute.Register(appGroup.Group("/users"), cfg, svc)
eligibilityroute.Register(appGroup.Group("/eligibility"), cfg, svc)
tncroute.Register(appGroup.Group("/rides"), cfg, svc, tnc, notification)
visitroute.Register(appGroup.Group("/visits"), cfg, svc, tnc)
visitroute.Register(appGroup.Group("/visits"), cfg, svc)
providerroute.Register(appGroup.Group("/provider"), cfg, svc)
placesroute.Register(appGroup.Group("/places"), cfg, svc)
profileroute.Register(appGroup.Group("/profile"), cfg, svc)
organizationroute.Register(appGroup.Group("/organization"), cfg, svc)
}

View File

@@ -39,7 +39,7 @@ func ResponseAPIErrorWithData(c echo.Context, status int, message string, redire
Error: true,
Message: message,
Redirect: redirect,
Data: data,
Data: data,
}
return c.JSON(status, returnValue)
@@ -92,19 +92,9 @@ func ResponseAPINotFoundError(c echo.Context) error {
return ResponseAPIError(c, http.StatusNotFound, "Not Found", false)
}
//ResponseAPINotEligibleError returns a standard API not eligible to the response
//ResponseAPINotEligible returns a standard API not eligible to the response
func ResponseAPINotEligibleError(c echo.Context) error {
return ResponseAPIError(c, http.StatusForbidden, "Member does not have active insurance coverage", false)
}
//ResponseAPINotEligibleWithMessageError returns a standard API not eligible to the response with custom message
func ResponseAPINotEligibleWithMessageError(c echo.Context, message string) error {
return ResponseAPIError(c, http.StatusForbidden, message, false)
}
//ResponseAPIPasswordResetFailed returns a standard API error when password reset fails
func ResponseAPIPasswordResetFailed(c echo.Context, message string) error {
return ResponseAPIError(c, http.StatusForbidden, message, false)
return ResponseAPIError(c, http.StatusForbidden, "Eligibility Not Found or Error", false)
}
func ignoreDefaultWrappedErrors(c echo.Context, errorToHandle *errors.WrappedError, handler func(echo.Context, error) error) error {

View File

@@ -1,183 +0,0 @@
package selfregisterroute
import (
"fmt"
"strings"
"sync"
b64 "encoding/base64"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
"bitbucket.org/nemt/nemt-portal-api/application/third/npd/npdmodel"
"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"
"bitbucket.org/nemt/nemt-portal-api/server/validation"
"github.com/labstack/echo"
)
const (
notificationEmailSubject = "Registration sucessful"
notificationEmailBody = "You have registered as a Visit Reporter for CHM NEMT.\nLogin: https://portal.bcbsinstitute.com\nReset PW: https://portal.bcbsinstitute.com/forgot"
notificationSmsBody = "You have registered as a Visit Reporter for CHM NEMT. Login: https://portal.bcbsinstitute.com Reset PW: https://portal.bcbsinstitute.com/forgot"
)
const (
phoneNumberMaxLength = 12
)
var (
instance *controller
once sync.Once
)
type controller struct {
svc *applicationservice.Service
cfg *config.Config
bcbsi *bcbsi.Service
}
func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *controller {
once.Do(func() {
instance = &controller{
svc: svc,
cfg: cfg,
bcbsi: bcbsi.New(cfg),
}
})
return instance
}
func removeNonNumberChars(input string) string {
result := ""
for _, char := range input {
if char >= '0' && char <= '9' {
result += string(char)
}
}
return result
}
func (c *controller) handle(ctx echo.Context) error {
var user viewmodel.User
if err := ctx.Bind(&user); err != nil {
return routeutils.HandleAPIError(ctx, err)
}
//format phone number - max length in database is 12 chars
formatedPhoneNumber := strings.TrimSpace(*user.PhoneNumber)
formatedPhoneNumber = strings.Replace(formatedPhoneNumber, "+1", "", -1)
formatedPhoneNumber = removeNonNumberChars(formatedPhoneNumber)
if len(formatedPhoneNumber) > phoneNumberMaxLength {
formatedPhoneNumber = formatedPhoneNumber[:phoneNumberMaxLength]
}
*user.PhoneNumber = formatedPhoneNumber
authUser, err := c.svc.Users.GetByUUID("573c70ff-733d-11e7-ba8f-0a6ad3fcdeaa", "")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
pass, err := b64.StdEncoding.DecodeString(user.Pass)
if err != nil {
return routeutils.ResponseAPIValidationError(ctx, "Invalid password")
}
user.Pass = string(pass)
if validationErrors := validation.ValidateSelfregistration(&user); len(validationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "Self registration failed", validationErrors)
}
if len(user.First) != 0 && len(user.Last) != 0 {
user.Name = fmt.Sprintf("%s %s", user.First, user.Last)
}
provider, err := c.svc.Provider.GetByNPI(user.Provider.InternalID, authUser)
if err != nil {
fmt.Println("Error to create organization", err)
return routeutils.HandleAPIError(ctx, err)
}
var organization viewmodel.Organization
if provider.ProviderUUID == "" {
org := viewmodel.Organization{
Author: authUser,
LastEditor: authUser,
Name: user.Provider.OrganizatioName,
Type: viewmodel.OrganizationType{
Key: "provider",
Name: "Provider",
},
Reference: npdmodel.ProviderResponse{
OrgName: user.Provider.OrganizatioName,
FivePartKeyGroups: []npdmodel.PartKeyGroup{
npdmodel.PartKeyGroup{
ProviderNum: user.Provider.InternalID,
},
},
},
}
organization, err = c.svc.Organization.AddOrganization(org, authUser)
if err != nil {
fmt.Println("Error to create organization", err)
return routeutils.HandleAPIError(ctx, err)
}
if organization.UUID == "" {
return routeutils.ResponseAPIValidationError(ctx, "Error to create organization")
}
} else {
organization = provider.Organization
}
user.Organizations = []viewmodel.Organization{organization}
user.Profiles = []viewmodel.Profile{viewmodel.Profile{
Name: "Visit Reporter",
Key: "VIRPT",
Organization: organization,
}}
user, err = c.svc.Users.Create(user, authUser)
if err != nil {
fmt.Println("Error to create user", err)
return routeutils.HandleAPIError(ctx, err)
}
//Send email notification to Authorized user
notification := viewmodel.Notification{
Type: applicationservice.NotificationTypeEmail,
From: c.cfg.Email.Sender,
To: *user.Email,
Subject: notificationEmailSubject,
Message: notificationEmailBody,
}
notification, err = c.svc.Notification.SendNotificationWithoutWritingToDatabase(notification)
if err != nil {
logger := ctx.Logger()
logger.Warnf("Application Error: Could not send email notification to user email : %s", *user.Email)
}
//Send sms notification to Authorized user
formatedPhoneNumber = *user.PhoneNumber
notification = viewmodel.Notification{
Type: applicationservice.NOtificationTypeSMS,
To: *user.PhoneNumber,
Message: notificationSmsBody,
}
notification, err = c.svc.Notification.SendNotificationWithoutWritingToDatabase(notification)
if err != nil {
logger := ctx.Logger()
logger.Warnf("Application Error: Could not send sms notification to user mobile : %s", *user.PhoneNumber)
}
return routeutils.ResponseAPIOK(ctx, user)
}

View File

@@ -1,18 +0,0 @@
package selfregisterroute
import (
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"github.com/labstack/echo"
)
const (
rootRoute = "/"
)
// Register registers the routes in the echo group
func Register(r *echo.Group, cfg *config.Config, svc *applicationservice.Service) {
ctrl := controllerInstance(svc, cfg)
r.POST(rootRoute, ctrl.handle)
}

View File

@@ -228,9 +228,12 @@ func (c *controller) handle(ctx echo.Context) error {
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if user.ID == "" {
return routeutils.ResponseAPIValidationError(ctx, "User not found")
}
//Validate ride request
if validationErrors := validation.ValidateRide(&requestRide, &user); len(validationErrors) > 0 {
if validationErrors := validation.ValidateRide(&requestRide, &user) ; len(validationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "ride validation failed", validationErrors)
}
@@ -239,42 +242,6 @@ func (c *controller) handle(ctx echo.Context) error {
return routeutils.HandleAPIError(ctx, err)
}
var provider viewmodel.ProviderResp
provider, err = c.svc.Provider.GetByNPI(requestRide.RawProvider.FivePartKeyGroups[0].ProviderNum, createdUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
fmt.Println("Provider Found: ", provider.ProviderUUID)
if provider.ProviderUUID == "" {
org := viewmodel.Organization{
Type: viewmodel.OrganizationType{
Key: "provider",
Name: "Provider",
},
Name: requestRide.RawProvider.OrgName,
Description: requestRide.RawProvider.OrgName,
Main: false,
Author: createdUser,
LastEditor: createdUser,
Reference: requestRide.RawProvider,
}
org, err = c.svc.Organization.AddOrganization(org, createdUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
fmt.Println("Organization Created: ", org.UUID)
provider, err = c.svc.Provider.GetByOrganization(org.UUID, createdUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
fmt.Println("Provider Found: ", provider.ProviderUUID)
}
requestRide.Provider = provider
requestRide.Destination.ID = provider.MukID
name := user.Name
names := strings.Split(name, " ")
requestRide.Passenger.FirstName = names[0]
@@ -289,7 +256,7 @@ func (c *controller) handle(ctx echo.Context) error {
requestRide.Destination = newOrigin
}
if createdUser.Test {
if c.cfg.LyftProd.UserUUID != createdUser.ID {
resp, err = c.tnc.Lyft.RequestRide(requestRide)
} else {
fmt.Println("In Production")
@@ -340,14 +307,14 @@ func (c *controller) handle(ctx echo.Context) error {
if requestRide.TripType.Key == "from_visit" {
resp.Origin.Name = requestRide.Destination.Name
resp.Origin.ID = requestRide.Provider.MukID
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.Provider.MukID
resp.Destination.ID = requestRide.Destination.ID
}
resp.Distance = requestRide.Distance
@@ -374,7 +341,6 @@ func (c *controller) handle(ctx echo.Context) error {
entity, err := c.svc.Rides.Save(resp)
if err != nil {
fmt.Println("Error to save rides: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
@@ -404,7 +370,7 @@ func (c *controller) handle(ctx echo.Context) error {
newRide.Passenger.LastName = " "
newRide.Passenger.PhoneNumber = *user.PhoneNumber
if createdUser.Test {
if c.cfg.LyftProd.UserUUID != createdUser.ID {
newRide, err = c.tnc.Lyft.RequestRide(newRide)
} else {
fmt.Println("In Production")
@@ -473,7 +439,7 @@ func (c *controller) handle(ctx echo.Context) error {
go func() {
err = c.svc.Notification.SendNotification(newRide.Status, roudtripRide, newRide)
if err != nil {
fmt.Println("Error notifying user: ", err.Error())
fmt.Println("Error to notify user: ", err.Error())
}
}()
}
@@ -514,7 +480,7 @@ func (c *controller) handleRawLyft(ctx echo.Context) error {
}
var lyftRide viewmodel.RideRequest
if user.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
} else {
fmt.Println("In Production")
@@ -546,7 +512,7 @@ func (c *controller) handleRideETA(ctx echo.Context) error {
if ride.Status.Key == "accepted" || ride.Status.Key == "pickedUp" || ride.Status.Key == "arrived" {
var lyftRide viewmodel.RideRequest
if user.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
} else {
fmt.Println("In Production")
@@ -614,7 +580,7 @@ func (c *controller) handleCancel(ctx echo.Context) error {
requestRide.RideID = "s_" + ride.InternalID
}
if user.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
err = c.tnc.Lyft.CancelRide(requestRide)
if err != nil && err.Error() == "ride_not_found" {
err = nil
@@ -719,7 +685,7 @@ func (c *controller) handleRide(ctx echo.Context) error {
if ride.Status.Key == "accepted" || ride.Status.Key == "pickedUp" || ride.Status.Key == "arrived" {
var lyftRide viewmodel.RideRequest
if user.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
} else {
fmt.Println("In Production")
@@ -858,7 +824,7 @@ func (c *controller) handleReady(ctx echo.Context) error {
}
var lyftRide viewmodel.RideRequest
if user.Test {
if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID})
} else {
fmt.Println("In Production")
@@ -880,7 +846,7 @@ func (c *controller) handleReady(ctx echo.Context) error {
lyftRide.Passenger.PhoneNumber = *nextRide.User.PhoneNumber
lyftRide.RideType = "lyft"
if user.Test {
if c.cfg.LyftProd.UserUUID != nextRide.CreatedUser.ID {
lyftRide, err = c.tnc.Lyft.RequestRide(lyftRide)
} else {
fmt.Println("In Production")
@@ -909,4 +875,4 @@ func (c *controller) handleReady(ctx echo.Context) error {
}()
return routeutils.ResponseAPIOK(ctx, nextRide)
}
}

View File

@@ -128,13 +128,6 @@ func (c *controller) handleTwilio(ctx echo.Context) error {
message = fmt.Sprintf("We received a request to cancel a ride from you at %s, but cannot find a ride for this mobile number.", libphonenumber.Format(num, libphonenumber.NATIONAL))
}
}
authUser, err := c.svc.Users.GetByUUID(lastRide.CreatedUser.ID, "")
if err != nil {
fmt.Println("Error to author of the ride: ", err.Error())
message = "There was a problem to call your ride"
}
if !isDriver {
if requestMessage == "I AM READY" && lastRide.UUID != "" {
if (lastRide.Visit.TripType.Key == "roundtrip_call" && (lastRide.TripType.Key == "to_visit" || lastRide.TripType.Key == "from_visit_call")) || lastRide.Visit.TripType.Key == "from_visit_call" {
@@ -168,7 +161,7 @@ func (c *controller) handleTwilio(ctx echo.Context) error {
lyftRide.Passenger.PhoneNumber = *readyRide.User.PhoneNumber
lyftRide.RideType = "lyft"
if authUser.Test {
if c.cfg.LyftProd.UserUUID != readyRide.CreatedUser.ID {
lyftRide, err = c.tnc.Lyft.RequestRide(lyftRide)
} else {
fmt.Println("In Production")
@@ -216,7 +209,7 @@ func (c *controller) handleTwilio(ctx echo.Context) error {
if requestMessage == "YES" && lastRide.UUID != "" {
var lyftRide viewmodel.RideRequest
if authUser.Test {
if lastRide.CreatedUser.ID != c.cfg.LyftProd.UserUUID {
lyftRide, err = c.tnc.Lyft.GetRideDetails(viewmodel.RideRequest{RideID: lastRide.InternalID})
if err != nil {
fmt.Println("Error: ", err.Error())

View File

@@ -15,13 +15,11 @@ import (
"bitbucket.org/nemt/nemt-portal-api/infra/cache"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"bitbucket.org/nemt/nemt-portal-api/server/authorization"
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
"bitbucket.org/nemt/nemt-portal-api/server/validation"
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
"github.com/labstack/echo"
)
const (
zipcodeTrimLength = 5
"golang.org/x/net/context"
"googlemaps.github.io/maps"
)
var (
@@ -334,6 +332,7 @@ func (c *controller) handleGetPortal(ctx echo.Context) error {
}
func (c *controller) handleMember(ctx echo.Context) error {
fmt.Println("\n\nHandle member\n\n")
var user viewmodel.User
if err := ctx.Bind(&user); err != nil {
return routeutils.HandleAPIError(ctx, err)
@@ -348,24 +347,107 @@ func (c *controller) handleMember(ctx echo.Context) error {
return routeutils.ResponseAPIAuthError(ctx, "phonenumber or email is required", false)
}
provider, err := c.svc.Provider.GetByNPI("1699849786", authUser)
if err != nil {
return routeutils.ResponseAPIAuthError(ctx, "Provider not found", false)
if len(user.Pass) == 0 {
user.Pass = c.generatePassword(8)
} else {
pass, err := b64.StdEncoding.DecodeString(user.Pass)
if err != nil {
return routeutils.ResponseAPIAuthError(ctx, "Invalid password", false)
}
user.Pass = string(pass)
}
user, err = c.svc.Users.CheckAndCreateMember(user, provider, authUser)
if user.BirthDate == nil || user.BirthDate.IsZero() {
return routeutils.ResponseAPIAuthError(ctx, "birthdate is required", false)
}
if user.Member == nil || len(*user.Member) == 0 {
return routeutils.ResponseAPIAuthError(ctx, "member is required", false)
}
if user.Gender == nil || len(*user.Gender) == 0 || (*user.Gender != "M" && *user.Gender != "F" && *user.Gender != "U") {
return routeutils.ResponseAPIAuthError(ctx, "gender is required", false)
}
if len(user.Name) == 0 && len(user.First) == 0 && len(user.Last) == 0 {
return routeutils.ResponseAPIAuthError(ctx, "name is required", false)
}
if len(user.First) != 0 && len(user.Last) != 0 {
user.Name = fmt.Sprintf("%s %s", user.First, user.Last)
}
profile, err := c.svc.Profile.GetByKey("US")
if err != nil {
if validationError, ok := err.(*viewmodel.ValidationError); ok {
if len(validationError.Errors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, validationError.Message, validationError.Errors)
} else {
return routeutils.ResponseAPIServiceError(ctx, validationError.Message)
}
} else {
return routeutils.HandleAPIError(ctx, err)
return routeutils.HandleAPIError(ctx, err)
}
user.Profiles = append(user.Profiles, profile)
eligibility := viewmodel.Eligibility{}
eligibility.Provider.ProviderNPI = "1699849786"
eligibility.Provider.ProviderName = "LITHOLINK CORPORATION"
eligibility.TrackingID = user.ID
eligibility.Subscriber.SubscriberID = *user.Member
eligibility.Subscriber.PatientType = "S"
eligibility.Subscriber.Name.First = user.First
eligibility.Subscriber.Name.Last = user.Last
eligibility.Subscriber.DemographicInfo.DateOfBirth = *user.BirthDate
eligibility.Subscriber.DemographicInfo.Gender = *user.Gender
eligibility.ServiceInfo.DateOfService = time.Now()
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
fmt.Println("\n\nGet271\n\n")
resp, err := c.bcbsi.BXE.Get271(eligibility)
if err != nil {
fmt.Println("Eligibility Not Found or Error: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
address := viewmodel.Address{}
header := resp.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N3_0950
body := resp.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N4_0960
address.AddressTypeName = "Home"
address.AddressType = "home"
address.Name = fmt.Sprintf("%s, %s", header.N301, body.N401)
address.Address = fmt.Sprintf("%s, %s", header.N301, body.N401)
address.CreatedUserUUID = authUser.ID
address.User = user
googleMapsAPI, err := maps.NewClient(maps.WithClientIDAndSignature("gme-bluecrossandblue1", "msqgD-jdqCyR0M_1u5C1HION5iI="))
if err != nil {
fmt.Println("Error to instantiate googles api: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
r := &maps.GeocodingRequest{
Address: address.Address + " " + body.N402 + ", " + body.N403,
}
result, err := googleMapsAPI.Geocode(context.Background(), r)
if err != nil {
fmt.Println("Error to instantiate googles api: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
if len(result) > 0 {
address.Latitude = result[0].Geometry.Location.Lat
address.Longitude = result[0].Geometry.Location.Lng
_, err := c.svc.Users.SaveAddress(address)
if err != nil {
fmt.Println("Error to save address: ", err.Error())
return routeutils.ResponseAPINotEligibleError(ctx)
}
}
//Get ZIP code and check if it is participating
user, err = c.svc.Users.Create(user, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
return routeutils.ResponseAPIOK(ctx, user)
}
@@ -407,7 +489,6 @@ func (c *controller) handleBulkPortal(ctx echo.Context) error {
return routeutils.ResponseAPIAuthError(ctx, "name is required", false)
}
users[i].Test = true
if len(users[i].First) != 0 && len(users[i].Last) != 0 {
users[i].Name = fmt.Sprintf("%s %s", users[i].First, users[i].Last)
}
@@ -458,7 +539,7 @@ func (c *controller) handlePortal(ctx echo.Context) error {
}
user.Pass = string(pass)
if passwordValidationErrors := validation.ValidatePassword(&user); len(passwordValidationErrors) > 0 {
if passwordValidationErrors := validation.ValidatePassword(&user) ; len(passwordValidationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "Password not strong enough", passwordValidationErrors)
}
@@ -469,7 +550,6 @@ func (c *controller) handlePortal(ctx echo.Context) error {
if len(user.First) != 0 && len(user.Last) != 0 {
user.Name = fmt.Sprintf("%s %s", user.First, user.Last)
}
user.Test = true
user, err = c.svc.Users.Create(user, authUser)
if err != nil {

View File

@@ -1,22 +1,13 @@
package visitroute
import (
"fmt"
"math/rand"
"strings"
"sync"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
"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"
)
var (
@@ -25,428 +16,33 @@ var (
)
type controller struct {
svc *applicationservice.Service
cfg *config.Config
bcbsi *bcbsi.Service
tnc *tncservice.Service
svc *applicationservice.Service
cfg *config.Config
}
func controllerInstance(svc *applicationservice.Service, cfg *config.Config, tnc *tncservice.Service) *controller {
func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *controller {
once.Do(func() {
instance = &controller{
svc: svc,
cfg: cfg,
bcbsi: bcbsi.New(cfg),
tnc: tnc,
svc: svc,
cfg: cfg,
}
})
return instance
}
func (c *controller) generatePassword(n int) string {
const (
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
return c.stringWithCharset(n, charset)
}
func (c *controller) stringWithCharset(length int, charset string) string {
b := make([]byte, length)
var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}
func (c *controller) handleRide(ctx echo.Context) error {
var ride viewmodel.RideRequest
if err := ctx.Bind(&ride); err != nil {
fmt.Println(err)
return routeutils.ResponseAPIValidationError(ctx, "invalid parameters")
}
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
visit, err := c.svc.Visits.GetByUUID(ride.Visit.UUID, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
visit.User.PhoneNumber = ride.User.PhoneNumber
visit.User.Email = ride.User.Email
visit.User.Consent = true
ride.Visit = visit
var provider viewmodel.ProviderResp
provider, err = c.svc.Provider.GetByUUID(ride.Visit.Provider.ProviderUUID, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
ride.Visit.Provider = provider
user, err := c.svc.Users.CheckAndCreateMember(ride.Visit.User, provider, authUser)
if err != nil {
if validationError, ok := err.(*viewmodel.ValidationError); ok {
if len(validationError.Errors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, validationError.Message, validationError.Errors)
} else {
return routeutils.ResponseAPIServiceError(ctx, validationError.Message)
}
} else {
return routeutils.HandleAPIError(ctx, err)
}
}
ride.Visit.User = user
ride.User = user
homeAddress := viewmodel.Address{}
for _, a := range visit.User.Addresses {
if a.AddressType == "home" {
homeAddress = a
}
}
ride.CreateUserUUID = authUser.ID
ride.Destination = viewmodel.Location{
ID: visit.Provider.ProviderUUID,
Name: visit.Provider.OrganizatioName,
Latitude: visit.Provider.Address.Latitude,
Longitude: visit.Provider.Address.Longitude,
Address: visit.Provider.Address.StreetAddress1,
}
if len(ride.Origin.ID) == 0 {
ride.Origin = viewmodel.Location{
ID: homeAddress.UUID,
Name: homeAddress.AddressTypeName,
Latitude: homeAddress.Latitude,
Longitude: homeAddress.Longitude,
Address: homeAddress.Address,
}
}
ride.Notes = ride.Notes
ride.Passenger.FirstName = visit.User.First
ride.Passenger.LastName = " "
ride.Passenger.PhoneNumber = *visit.User.PhoneNumber
ride.RideType = "lyft"
ride.VisitDate = &visit.VisitDatetime
ride.VisitTime = &visit.VisitDatetime
ride.UserConsent = true
if validationErrors := validation.ValidateVisitRide(&ride, &user); len(validationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "ride validation failed", validationErrors)
}
var resp viewmodel.RideRequest
if ride.TripType.Key != "from_visit_call" {
if ride.TripType.Key == "from_visit" {
newOrigin := ride.Origin
ride.Origin = ride.Destination
ride.Destination = newOrigin
}
if authUser.Test {
resp, err = c.tnc.Lyft.RequestRide(ride)
} else {
fmt.Println("In Production")
resp, err = c.tnc.LyftProd.RequestRide(ride)
}
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if ride.TripType.Key == "from_visit" {
newOrigin := resp.Origin
resp.Origin = resp.Destination
resp.Destination = newOrigin
}
resp.RideID = strings.Replace(resp.RideID, "s_", "", -1)
} else {
resp = ride
UUID, _ := uuid.NewV4()
resp.RideID = UUID.String()
}
if resp.Status == "scheduled" || ride.TripType.Key == "from_visit_call" {
if ride.PickupTime == nil {
currentDate := time.Now()
ride.PickupTime = &currentDate
}
requestMS := (ride.PickupTime.UnixNano() / int64(time.Millisecond))
generateDate := time.Now()
generateMS := (generateDate.UnixNano() / int64(time.Millisecond))
resp.RequestAt = ride.PickupTime
resp.RequestAtMS = &requestMS
resp.GeneratedAt = &generateDate
resp.GeneratedAtMS = &generateMS
}
resp.Passenger.FirstName = visit.User.First
resp.Passenger.LastName = visit.User.Last
resp.Passenger.PhoneNumber = *visit.User.PhoneNumber
if resp.Passenger.ImageURL == nil {
imageURL := " "
resp.Passenger.ImageURL = &imageURL
}
resp.UserUUID = visit.User.ID
if ride.TripType.Key == "from_visit" {
resp.Origin.Name = ride.Destination.Name
resp.Origin.ID = ride.Destination.ID
resp.Destination.Name = ride.Origin.Name
resp.Destination.ID = ride.Origin.ID
} else {
resp.Origin.Name = ride.Origin.Name
resp.Origin.ID = ride.Origin.ID
resp.Destination.Name = ride.Destination.Name
resp.Destination.ID = ride.Destination.ID
}
resp.Distance = ride.Distance
resp.Duration = ride.Duration
resp.ETA = ride.ETA
resp.PickupTime = ride.PickupTime
resp.VisitDate = &ride.Visit.VisitDatetime
resp.VisitTime = &ride.Visit.VisitDatetime
resp.VisitExternalID = ride.Visit.ExternalID
resp.CreateUserUUID = authUser.ID
resp.Visit.TripType = ride.Visit.TripType
resp.Visit = visit
if resp.TripType.Key == "from_visit_call" {
resp.Status = "willCall"
resp.Passenger.UserID = &resp.UserUUID
}
resp.TripType.Key = ride.TripType.Key
if ride.TripType.Key == "roundtrip" || ride.TripType.Key == "roundtrip_call" {
resp.TripType.Key = "to_visit"
} else if ride.TripType.Key == "from_visit_call" {
resp.TripType.Key = "from_visit_call"
}
entity, err := c.svc.Rides.Save(resp)
if err != nil {
fmt.Println("Error to save first ride: ", err.Error())
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 ride.TripType.Key == "roundtrip" || ride.TripType.Key == "roundtrip_call" {
newRide := ride
if ride.TripType.Key == "roundtrip" {
destination := newRide.Origin
newRide.Origin = newRide.Destination
newRide.Destination = destination
if ride.ReturnTime != nil {
newRide.PickupTime = ride.ReturnTime
}
scheduledRide := make(map[string]interface{})
scheduledRide["timestamp_ms"] = ride.PickupTime.Unix()
newRide.ScheduledPickupRange = scheduledRide
newRide.Passenger.FirstName = visit.User.First
newRide.Passenger.LastName = " "
newRide.Passenger.PhoneNumber = *visit.User.PhoneNumber
if authUser.Test {
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 = visit
newRide.PickupTime = ride.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 = visit.User.First
newRide.Passenger.LastName = visit.User.Last
newRide.Passenger.PhoneNumber = *visit.User.PhoneNumber
newRide.Passenger.UserID = &ride.UserUUID
if newRide.Passenger.ImageURL == nil {
imageURL := " "
newRide.Passenger.ImageURL = &imageURL
}
newRide.UserUUID = ride.UserUUID
newRide.Origin.Name = ride.Destination.Name
newRide.Origin.ID = ride.Destination.ID
newRide.Destination.Name = ride.Origin.Name
newRide.Destination.ID = ride.Origin.ID
newRide.Distance = ride.Distance
newRide.Duration = ride.Duration
newRide.ETA = ride.ETA
newRide.VisitDate = ride.VisitDate
newRide.VisitTime = ride.VisitTime
newRide.VisitExternalID = ride.VisitExternalID
newRide.CreateUserUUID = authUser.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 to notify user: ", err.Error())
}
}()
}
ctx.Response().Header().Set("Content-Type", "application/json")
return routeutils.ResponseAPIOK(ctx, entity)
}
func (c *controller) rangeIn(low, hi int) string {
result := low + rand.Intn(hi-low)
return fmt.Sprintf("%v", result)
}
func (c *controller) handle(ctx echo.Context) error {
var visit viewmodel.Visit
if err := ctx.Bind(&visit); err != nil {
fmt.Println(err)
return routeutils.ResponseAPIValidationError(ctx, "invalid parameters")
}
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
var provider viewmodel.ProviderResp
provider, err = c.svc.Provider.GetByNPI(visit.RawProvider.FivePartKeyGroups[0].ProviderNum, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if provider.ProviderUUID == "" {
org := viewmodel.Organization{
Type: viewmodel.OrganizationType{
Key: "provider",
Name: "Provider",
},
Name: visit.RawProvider.OrgName,
Description: visit.RawProvider.OrgName,
Main: false,
Author: authUser,
LastEditor: authUser,
Reference: visit.RawProvider,
}
org, err = c.svc.Organization.AddOrganization(org, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
provider, err = c.svc.Provider.GetByOrganization(org.UUID, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
}
visit.Provider = provider
if validationErrors := validation.ValidateVisit(&visit, &authUser); len(validationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "visit validation failed", validationErrors)
}
user, err := c.svc.Users.CheckAndCreateMember(visit.User, provider, authUser)
if err != nil {
if validationError, ok := err.(*viewmodel.ValidationError); ok {
if len(validationError.Errors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, validationError.Message, validationError.Errors)
} else {
return routeutils.ResponseAPIServiceError(ctx, validationError.Message)
}
} else {
return routeutils.HandleAPIError(ctx, err)
}
}
visit.User = user
visit.TripType = viewmodel.TripType{
Key: "no_trip",
Value: "No Trip",
}
visit.User = user
visit.CreatedUser = authUser
visit, err = c.svc.Visits.Save(visit)
if err != nil {
fmt.Println("Error saving visit: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
if authUser.Profiles[0].Key == "VIRPT" {
return routeutils.ResponseNoContent(ctx, nil)
} else {
return routeutils.ResponseAPIOK(ctx, visit)
}
}
func (c *controller) handleGetByID(ctx echo.Context) error {
visit_uuid := ctx.Param("visit_uuid")
if visit_uuid == "" {
return routeutils.ResponseAPIValidationError(ctx, "visit_uuid param is mandatory")
}
authUser, err := auth.GetUserDetail(ctx, c.cfg)
user, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
resp, err := c.svc.Visits.GetByUUID(visit_uuid, authUser)
resp, err := c.svc.Visits.GetByUUID(visit_uuid, user)
if err != nil {
fmt.Println("Error to get Visit: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}

View File

@@ -2,7 +2,6 @@ package visitroute
import (
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
"bitbucket.org/nemt/nemt-portal-api/application/tncservice"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"github.com/labstack/echo"
)
@@ -10,15 +9,11 @@ import (
const (
rootRoute = "/"
idRoute = "/:visit_uuid"
rideRoute = "/:visit_uuid/ride"
)
// Register registers the routes in the echo group
func Register(r *echo.Group, cfg *config.Config, svc *applicationservice.Service, tnc *tncservice.Service) {
ctrl := controllerInstance(svc, cfg, tnc)
r.POST(rootRoute, ctrl.handle)
r.POST(rideRoute, ctrl.handleRide)
func Register(r *echo.Group, cfg *config.Config, svc *applicationservice.Service) {
ctrl := controllerInstance(svc, cfg)
r.GET(rootRoute, ctrl.handleGetAll)
r.GET(idRoute, ctrl.handleGetByID)

View File

@@ -18,9 +18,7 @@ func authSkipper(ctx echo.Context) bool {
strings.Contains(path, "/v1/ext") ||
strings.Contains(path, "/v1/notification/ws") ||
strings.HasPrefix(path, "/v1/lyfthook") ||
strings.HasPrefix(path, "/v1/docs") ||
strings.HasPrefix(path, "/v1/selfregister") ||
strings.HasPrefix(path, "/v1/passwordreset"))
strings.HasPrefix(path, "/v1/docs"))
}
// appSkipper is the default skipper for the application routes

View File

@@ -1,150 +0,0 @@
package validation
import (
"regexp"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
const (
firstNameMaxLength = 50
lastNameMaxLength = 50
emailMaxLength = 150
memberNumberValidNumberOfLetters = 3
)
const (
formModeVisit = 1
formModeRide = 2
)
func isAlphabetic(input string) bool {
for _, character := range input {
if !(characterIsUpperCase(character) || characterIsLowerCase(character)) {
return false
}
}
return true
}
func isNumeric(input string) bool {
for _, character := range input {
if !characterIsNumber(character) {
return false
}
}
return true
}
func isEmailValid(email string) bool {
validEmailRegex := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
return validEmailRegex.MatchString(email)
}
func isMemberNumberValid(input string) bool {
if len(input) < memberNumberValidNumberOfLetters {
return false
}
if !isAlphabetic(input[:memberNumberValidNumberOfLetters]) {
return false
}
if !isNumeric(input[memberNumberValidNumberOfLetters:]) {
return false
}
return true
}
func ValidateEligibility(user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
formMode := formModeVisit // This should be red from request, not hardcoded
//First name validation
if len(user.First) < 1 {
result = append(result, errors.ValidationError{Field: "first", Message: "First Name is required"})
}
if !isAlphabetic(user.First) {
result = append(result, errors.ValidationError{Field: "first", Message: "First Name contains non-alphabetic characters"})
}
if len(user.First) > firstNameMaxLength {
result = append(result, errors.ValidationError{Field: "first", Message: "First Name is too long"})
}
//Last name validation
if len(user.Last) < 1 {
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is required"})
}
if !isAlphabetic(user.Last) {
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name contains non-alphabetic characters"})
}
if len(user.Last) > lastNameMaxLength {
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is too long"})
}
//Email validation
if user.Email != nil && len(*user.Email) > 0 {
if (formMode == formModeRide) && len(*user.Email) < 1 {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"})
}
if !isEmailValid(*user.Email) {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is invalid"})
}
if len(*user.Email) > emailMaxLength {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is too long"})
}
} else {
if formMode == formModeRide {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"})
}
}
//Gender validation
if ((user.Gender != nil) && len(*user.Gender) < 1) || (user.Gender == nil) {
result = append(result, errors.ValidationError{Field: "gender", Message: "Member Gender is required"})
}
//Member type validation
if (user.Type != nil && len(*user.Type) < 1) || (user.Type == nil) {
result = append(result, errors.ValidationError{Field: "type", Message: "Member Type is required"})
}
//Member# validation
if !isMemberNumberValid(*user.Member) {
result = append(result, errors.ValidationError{Field: "member", Message: "Member# is invalid"})
}
//Birthdate validation
if user.BirthDate == nil {
result = append(result, errors.ValidationError{Field: "birthdate", Message: "Choose a Birth Date"})
} else {
yesterday := time.Now().Add(-1 * time.Hour * hoursInDay)
if user.BirthDate.After(yesterday) {
result = append(result, errors.ValidationError{Field: "birthdate", Message: "Choose a valid Birth Date"})
}
}
//Mobile validation
if formMode == formModeRide {
if (user.PhoneNumber != nil && len(*user.PhoneNumber) < 1) || (user.PhoneNumber == nil) {
result = append(result, errors.ValidationError{Field: "phonenumber", Message: "Phone number is required"})
}
}
//User consent validation
if !user.Consent {
result = append(result, errors.ValidationError{Field: "consent", Message: "Must be 'Checked'"})
}
return result
}

View File

@@ -1,111 +0,0 @@
package validation
import (
"fmt"
"strings"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
const (
minimumPasswordLength = 8
)
func validateSelfregistrationPassword(user *viewmodel.User, result *[]errors.ValidationError) {
if len(user.Pass) < minimumPasswordLength {
*result = append(*result, errors.ValidationError{Field: "password", Message: fmt.Sprint("Password must be at least ", minimumPasswordLength, " characters.")})
}
if strings.Contains(user.Pass, user.First) {
*result = append(*result, errors.ValidationError{Field: "password", Message: "Password cannot include your First Name."})
}
if strings.Contains(user.Pass, user.Last) {
*result = append(*result, errors.ValidationError{Field: "password", Message: "Password cannot include your Last Name."})
}
containsUpperCaseLetter := false
containsLowerCaseLetter := false
containsNumber := false
for _, character := range user.Pass {
containsUpperCaseLetter = containsUpperCaseLetter || characterIsUpperCase(character)
containsLowerCaseLetter = containsLowerCaseLetter || characterIsLowerCase(character)
containsNumber = containsNumber || characterIsNumber(character)
}
if !containsUpperCaseLetter || !containsLowerCaseLetter || !containsNumber {
*result = append(*result, errors.ValidationError{Field: "password", Message: "Password must contain one of EACH :"})
*result = append(*result, errors.ValidationError{Field: "password-tab", Message: "an uppercase letter"})
*result = append(*result, errors.ValidationError{Field: "password-tab", Message: "a lowercase letter"})
*result = append(*result, errors.ValidationError{Field: "password-tab", Message: "a number"})
}
}
func ValidateSelfregistration(user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
//Provider Organization Name validation
if len(user.Provider.OrganizatioName) < 1 {
result = append(result, errors.ValidationError{Field: "provider.org_name", Message: "Provider Organization Name is required"})
}
//Provider NPI validation
if len(user.Provider.InternalID) != 10 || !isNumeric(user.Provider.InternalID) {
result = append(result, errors.ValidationError{Field: "provider.internal_id", Message: "Provider NPI must be 10 digit number"})
}
//First name validation
if len(user.First) < 1 {
result = append(result, errors.ValidationError{Field: "first", Message: "First Name is required"})
}
if !isAlphabetic(user.First) {
result = append(result, errors.ValidationError{Field: "first", Message: "First Name contains non-alphabetic characters"})
}
if len(user.First) > firstNameMaxLength {
result = append(result, errors.ValidationError{Field: "first", Message: "First Name is too long"})
}
//Last name validation
if len(user.Last) < 1 {
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is required"})
}
if !isAlphabetic(user.Last) {
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name contains non-alphabetic characters"})
}
if len(user.Last) > lastNameMaxLength {
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is too long"})
}
//Email validation
if user.Email != nil {
if len(*user.Email) < 1 {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"})
}
if !isEmailValid(*user.Email) {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is invalid"})
}
if len(*user.Email) > emailMaxLength {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is too long"})
}
} else {
result = append(result, errors.ValidationError{Field: "email", Message: "Email is required"})
}
//Mobile validation
if (user.PhoneNumber == nil) || len(*user.PhoneNumber) < 1 {
result = append(result, errors.ValidationError{Field: "phonenumber", Message: "Phone number is required"})
}
//Password validation
validateSelfregistrationPassword(user, &result)
return result
}

View File

@@ -1,229 +1,183 @@
package validation
import (
"fmt"
"regexp"
"strconv"
"time"
"fmt"
"strconv"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
const (
tripTypeFromVisit = "from_visit"
tripTypeToVisit = "to_visit"
tripTypeFromVisitWillCall = "from_visit_call"
tripTypeRoundTrip = "roundtrip"
tripTypeRountTripWillCall = "roundtrip_call"
tripTypeFromVisit = "From Visit"
tripTypeToVisit = "To Visit"
tripTypeFromVisitWillCall = "From Visit / Will Call"
tripTypeRoundTrip = "Round Trip"
tripTypeRountTripWillCall = "Round Trip / Will Call"
)
const (
loadingTime = 30 //in minutes
minimumLoadTime = 30 //in minutes
minimumPickupTime = 10 //in minutes
loadingTime = 30 //in minutes
minimumLoadTime = 30 //in minutes
minimumPickupTime = 10 //in minutes
)
const (
hoursInDay = 24
hoursIn180Days = 24 * 180
time8Hours = 8
time10Minutes = 10
hoursInDay = 24
hoursIn180Days = 24*180
time8Hours = 8
time10Minutes = 10
)
func isMixedIDValid(id string) bool {
hasUpperCase := false
hasLowerCase := false
hasNumber := false
for _, character := range id {
hasUpperCase = hasUpperCase || ((character >= 65) && (character <= 90))
hasLowerCase = hasLowerCase || ((character >= 97) && (character <= 122))
hasNumber = hasNumber || ((character >= 48) && (character <= 57))
}
return (hasUpperCase || hasLowerCase) && hasNumber
}
func ValidateVisitRide(requestRide *viewmodel.RideRequest, user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
if user.Email != nil && len(*user.Email) == 0 {
result = append(result, errors.ValidationError{Field: "email", Message: "Step #1 - Email is mandatory"})
}
if user.PhoneNumber != nil && len(*user.PhoneNumber) == 0 {
result = append(result, errors.ValidationError{Field: "phonenumber", Message: "Step #1 - Phonenumber is mandatory"})
}
rideValidation := ValidateRide(requestRide, user)
result = append(result, rideValidation...)
return result
}
func ValidateRide(requestRide *viewmodel.RideRequest, user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
var validUUIDregex = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`)
//Step #1 validation
if !validUUIDregex.MatchString(user.ID) {
result = append(result, errors.ValidationError{Field: "user_uuid", Message: "Step #1 - Choose a Member"})
if userID, err := strconv.Atoi(user.ID) ; err != nil || userID <= 0 {
result = append(result, errors.ValidationError{Field : "user_uuid", Message : "Step #1 - Choose a Member" })
}
fmt.Println("\n\n", requestRide.Origin.ID, "\n\n")
if !isMixedIDValid(requestRide.Origin.ID) {
//it is not UUID or similar to UUID, let's try with just a number
if originID, err := strconv.Atoi(requestRide.Origin.ID); err != nil || originID <= 0 {
//it is not a number
result = append(result, errors.ValidationError{Field: "origin.id", Message: "Step #1 - Choose a Pickup Address"})
}
if originID, err := strconv.Atoi(requestRide.Origin.ID) ; err != nil || originID <= 0 {
result = append (result, errors.ValidationError{Field : "origin.id", Message : "Step #1 - Choose a Pickup Address"})
}
if !requestRide.UserConsent {
result = append(result, errors.ValidationError{Field: "user_consent", Message: "Step #1 - Member must consent to Terms of Use"})
}
result = append (result, errors.ValidationError{Field : "user_consent", Message : "Step #1 - Member must consent to Terms of Use"})
}
//Step #2 validation
fmt.Println("\n\n", requestRide.Destination.ID, "\n\n")
if !isMixedIDValid(requestRide.Destination.ID) {
//it is not UUID or similar to UUID, let's try with just a number
if destinationID, err := strconv.Atoi(requestRide.Destination.ID); err != nil || destinationID <= 0 {
result = append(result, errors.ValidationError{Field: "destination.id", Message: "Step #2 - Choose a Provider"})
}
if destinationID, err := strconv.Atoi(requestRide.Destination.ID) ; err!= nil || destinationID <= 0 {
result = append (result, errors.ValidationError{Field : "destination.id", Message : "Step #2 - Choose a Provider"})
}
//Step #3 validation
isVisitDayToday := requestRide.VisitDate.Day() == time.Now().Day() && requestRide.VisitDate.Month() == time.Now().Month() && requestRide.VisitDate.Year() == time.Now().Year()
before8Hours := time.Now().Add(-time.Hour * time8Hours)
before8Hours := time.Now().Add(-time.Hour*time8Hours)
if requestRide.VisitDate == nil {
result = append(result, errors.ValidationError{Field: "visit_date", Message: "Step #3 - Choose a Date for the Visit"})
} else {
dayBeforeToday := time.Now().Add(-time.Hour * hoursInDay)
result = append (result, errors.ValidationError{Field : "visit_date", Message : "Step #3 - Choose a Date for the Visit"})
}else{
dayBeforeToday := time.Now().Add(-time.Hour*hoursInDay)
if requestRide.VisitDate.Before(dayBeforeToday) {
result = append(result, errors.ValidationError{Field: "visit_date", Message: "Step #3 - Visit cannot occur more than one day before today"})
result = append (result, errors.ValidationError{Field : "visit_date", Message : "Step #3 - Visit cannot occur more than one day before today"})
}
dayAfter180Days := time.Now().Add(time.Hour * hoursIn180Days)
dayAfter180Days := time.Now().Add(time.Hour*hoursIn180Days)
if requestRide.VisitDate.After(dayAfter180Days) {
result = append(result, errors.ValidationError{Field: "visit_date", Message: "Step #3 - Visit cannot occur more than 180 days after today"})
result = append (result, errors.ValidationError{Field : "visit_date", Message : "Step #3 - Visit cannot occur more than 180 days after today"})
}
if requestRide.VisitTime == nil {
result = append(result, errors.ValidationError{Field: "visit_time", Message: "Step #3 - Choose a Time for the Visit"})
} else {
result = append (result, errors.ValidationError{Field : "visit_time", Message : "Step #3 - Choose a Time for the Visit"})
}else{
if isVisitDayToday && requestRide.VisitTime.Before(before8Hours) {
result = append(result, errors.ValidationError{Field: "visit_time", Message: "Step #3 - Visit is more than 8 hours in the past"})
result = append (result, errors.ValidationError{Field : "visit_time", Message : "Step #3 - Visit is more than 8 hours in the past"})
}
}
}
//Step #4 validation
timeWithDurationAndLoadingTime := requestRide.VisitTime.Add(-time.Duration(requestRide.Duration) * time.Second).Add(-loadingTime * time.Minute)
after10Minutes := time.Now().Add(time.Minute * time10Minutes)
isTripTypeValid := true
switch requestRide.TripType.Key {
case tripTypeToVisit:
if requestRide.PickupTime == nil {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Choose a Pickup Time"})
} else {
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time less than required time before Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Visit cannot occour in the past"})
}
}
case tripTypeFromVisit:
if requestRide.PickupTime == nil {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Choose a Pickup Time"})
} else {
timeWithMinimumPickupTime := time.Now().Add(minimumPickupTime * time.Minute)
if isVisitDayToday && requestRide.PickupTime.Before(timeWithMinimumPickupTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: fmt.Sprint("Step #4 - Time must be more than %d minutes from now", minimumPickupTime)})
}
if requestRide.PickupTime.Before(*requestRide.VisitTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time less than required time after Visit Time"})
}
timeWithMinimumLoadTime := time.Now().Add(minimumLoadTime * time.Minute)
if requestRide.PickupTime.Before(timeWithMinimumLoadTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time less than Minimum Load Time before Visit Time"})
}
}
case tripTypeFromVisitWillCall:
//no special validation for this case
case tripTypeRoundTrip:
if requestRide.PickupTime == nil {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Choose a Pickup Time"})
} else {
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time less than required time before Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(after10Minutes) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time must be at least 10 minutes from now"})
}
}
if requestRide.ReturnTime == nil {
result = append(result, errors.ValidationError{Field: "return_time", Message: "Step #4 - Choose a Pickup Time"})
} else {
if isVisitDayToday {
if requestRide.ReturnTime.Before(before8Hours) {
result = append(result, errors.ValidationError{Field: "return_time", Message: "Step #4 - Return Time is more than 8 hours after Visit Time"})
}
if requestRide.ReturnTime.Before(after10Minutes) {
result = append(result, errors.ValidationError{Field: "return_time", Message: "Step #4 - Return Time must be at least 10 minutes from now"})
}
}
}
case tripTypeRountTripWillCall:
if requestRide.PickupTime == nil {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Choose a Pickup Time"})
} else {
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Pickup Time less than required time after Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Visit cannot occur in the past "})
}
}
default:
isTripTypeValid = false
if requestRide.TripType.Value == "" {
result = append (result, errors.ValidationError{Field : "trip_type.value", Message : "Step #4 - Choose a Trip Type"})
}
if !isTripTypeValid {
result = append(result, errors.ValidationError{Field: "trip_type.key", Message: "Step #4 - Choose a Trip Type"})
}
timeWithDurationAndLoadingTime := requestRide.VisitTime.Add(-time.Duration(requestRide.Duration)*time.Second).Add(-loadingTime*time.Minute)
after10Minutes := time.Now().Add(time.Minute*time10Minutes)
switch requestRide.TripType.Value {
case tripTypeToVisit:
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time before Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Visit cannot occour in the past"})
}
}
case tripTypeFromVisit :
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
timeWithMinimumPickupTime := time.Now().Add(minimumPickupTime*time.Minute)
if isVisitDayToday && requestRide.PickupTime.Before(timeWithMinimumPickupTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : fmt.Sprint("Step #4 - Time must be more than %d minutes from now",minimumPickupTime)})
}
if requestRide.PickupTime.Before(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time after Visit Time"})
}
timeWithMinimumLoadTime := time.Now().Add(minimumLoadTime*time.Minute)
if requestRide.PickupTime.Before(timeWithMinimumLoadTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than Minimum Load Time before Visit Time"})
}
}
case tripTypeFromVisitWillCall:
//no special validation for this case
case tripTypeRoundTrip:
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time before Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(after10Minutes) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must be at least 10 minutes from now"})
}
}
if requestRide.ReturnTime == nil {
result = append (result, errors.ValidationError{Field : "return_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if isVisitDayToday {
if requestRide.ReturnTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "return_time", Message : "Step #4 - Return Time is more than 8 hours after Visit Time"})
}
if requestRide.ReturnTime.Before(after10Minutes) {
result = append (result, errors.ValidationError{Field : "return_time", Message : "Step #4 - Return Time must be at least 10 minutes from now"})
}
}
}
case tripTypeRountTripWillCall:
if requestRide.PickupTime == nil {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Choose a Pickup Time"})
}else{
if requestRide.PickupTime.After(*requestRide.VisitTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time must occur before Visit Time"})
}
if requestRide.PickupTime.After(timeWithDurationAndLoadingTime) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Pickup Time less than required time after Visit Time"})
}
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
result = append (result, errors.ValidationError{Field : "pickup_time", Message : "Step #4 - Visit cannot occur in the past "})
}
}
}
return result
}
}

View File

@@ -1,10 +1,12 @@
package validation
import (
"strings"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
func characterIsUpperCase(character rune) bool {
@@ -23,31 +25,29 @@ func ValidatePassword(user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
userOrganizationName := ""
if len(user.Organizations) > 0 {
if len(user.Organizations) > 0{
userOrganizationName = user.Organizations[0].Name
}
if len(user.Pass) < 8 {
result = append(result, errors.ValidationError{Field: "password", Message: "Password must be at least 8 characters."})
if (len(user.Pass) < 8) {
result = append(result, errors.ValidationError{Field : "password", Message : "Password must be at least 8 characters."})
}
if strings.Contains(user.Pass, user.First) {
result = append(result, errors.ValidationError{Field: "password", Message: "Password cannot include your First Name."})
if (strings.Contains(user.Pass, user.First)){
result = append(result, errors.ValidationError{Field : "password", Message : "Password cannot include your First Name."})
}
if strings.Contains(user.Pass, user.Last) {
result = append(result, errors.ValidationError{Field: "password", Message: "Password cannot include your Last Name."})
if (strings.Contains(user.Pass, user.Last)){
result = append(result, errors.ValidationError{Field : "password", Message : "Password cannot include your Last Name."})
}
if len(userOrganizationName) > 0 {
if strings.Contains(user.Pass, userOrganizationName) {
result = append(result, errors.ValidationError{Field: "password", Message: "Password cannot include your Organization Name."})
}
if (strings.Contains(user.Pass, userOrganizationName)){
result = append(result, errors.ValidationError{Field : "password", Message : "Password cannot include your Organization Name."})
}
containsUpperCaseLetter := false
containsLowerCaseLetter := false
containsNumber := false
containsUpperCaseLetter := false;
containsLowerCaseLetter := false;
containsNumber := false;
for _, character := range user.Pass {
containsUpperCaseLetter = containsUpperCaseLetter || characterIsUpperCase(character)
@@ -56,11 +56,12 @@ func ValidatePassword(user *viewmodel.User) []errors.ValidationError {
}
if !containsUpperCaseLetter || !containsLowerCaseLetter || !containsNumber {
result = append(result, errors.ValidationError{Field: "password", Message: "Password must contain one of EACH :"})
result = append(result, errors.ValidationError{Field: "password-tab", Message: "an uppercase letter"})
result = append(result, errors.ValidationError{Field: "password-tab", Message: "a lowercase letter"})
result = append(result, errors.ValidationError{Field: "password-tab", Message: "a number"})
result = append(result, errors.ValidationError{Field : "password", Message : "Password must contain one of EACH :"})
result = append(result, errors.ValidationError{Field : "password-tab", Message : "an uppercase letter"})
result = append(result, errors.ValidationError{Field : "password-tab", Message : "a lowercase letter"})
result = append(result, errors.ValidationError{Field : "password-tab", Message : "a number"})
}
return result
}
}

View File

@@ -1,45 +0,0 @@
package validation
import (
"time"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/errors"
)
func ValidateVisit(visit *viewmodel.Visit, user *viewmodel.User) []errors.ValidationError {
var result []errors.ValidationError
// Step #1
if len(visit.Provider.ProviderUUID) == 0 {
result = append(result, errors.ValidationError{Field: "provider.id", Message: "Step #1 - Provider is required"})
}
// Step #2
eligibilityResult := ValidateEligibility(&visit.User)
if len(eligibilityResult) > 0 {
result = append(result, eligibilityResult...)
}
//Step #3
if visit.VisitDatetime.IsZero() {
result = append(result, errors.ValidationError{Field: "visit_datetime", Message: "Step #3 - Choose a Date for the Visit"})
} else {
isVisitDayToday := visit.VisitDatetime.Day() == time.Now().Day() && visit.VisitDatetime.Month() == time.Now().Month() && visit.VisitDatetime.Year() == time.Now().Year()
before8Hours := time.Now().Add(-time.Hour * time8Hours)
dayBeforeToday := time.Now().Add(-time.Hour * hoursInDay)
if visit.VisitDatetime.Before(dayBeforeToday) {
result = append(result, errors.ValidationError{Field: "visit_datetime", Message: "Step #3 - Visit cannot occur more than one day before today"})
}
dayAfter180Days := time.Now().Add(time.Hour * hoursIn180Days)
if visit.VisitDatetime.After(dayAfter180Days) {
result = append(result, errors.ValidationError{Field: "visit_datetime", Message: "Step #3 - Visit cannot occur more than 180 days after today"})
}
if isVisitDayToday && visit.VisitDatetime.Before(before8Hours) {
result = append(result, errors.ValidationError{Field: "visit_datetime", Message: "Step #3 - Visit is more than 8 hours in the past"})
}
}
return result
}