Compare commits
4 Commits
ride_valid
...
self-regis
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54ebc056d5 | ||
|
|
f1ac874276 | ||
|
|
756d84359d | ||
|
|
806e2b1f3b |
@@ -550,6 +550,56 @@ 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 {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package applicationservice
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
|
||||
@@ -183,6 +184,7 @@ 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)
|
||||
}
|
||||
|
||||
@@ -190,12 +192,14 @@ 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
|
||||
@@ -203,17 +207,20 @@ 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
|
||||
@@ -221,6 +228,7 @@ 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)
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ 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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +80,12 @@ func (mapping *userMapping) ToUserEntity(item viewmodel.User) entity.User {
|
||||
Types: mapping.mapper.Organization.ToOrganizationTypeEntitySlice(item.Types),
|
||||
}
|
||||
|
||||
if item.Type == nil {
|
||||
user.Type = "S"
|
||||
} else {
|
||||
user.Type = *item.Type
|
||||
}
|
||||
|
||||
if user.Name == "" {
|
||||
user.Name = fmt.Sprintf("%s %s", item.First, item.Last)
|
||||
}
|
||||
|
||||
@@ -119,11 +119,14 @@ 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)
|
||||
|
||||
@@ -14,50 +14,53 @@ 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"`
|
||||
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"`
|
||||
}
|
||||
|
||||
//Charge information
|
||||
@@ -159,4 +162,4 @@ type RideRoute struct {
|
||||
Duration int64 `json:"duration,omitempty"`
|
||||
ETA int64 `json:"eta,omitempty"`
|
||||
Bearing int64 `json:"bearing,omitempty"`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,3 +113,10 @@ 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
|
||||
|
@@ -29,7 +29,7 @@ func (c *rideRepo) getQuery() string {
|
||||
b.user_id,
|
||||
b.user_uuid,
|
||||
b.name,
|
||||
b.member,
|
||||
b.subscriber_id,
|
||||
c.ride_status_id,
|
||||
c.ride_status,
|
||||
c.key ride_status_key,
|
||||
@@ -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.member,
|
||||
a.subscriber_id,
|
||||
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.member, '') created_member,
|
||||
IFNULL(d.subscriber_id, '') created_member,
|
||||
e.trip_type_id,
|
||||
e.trip_type_key,
|
||||
e.trip_type
|
||||
|
||||
@@ -23,7 +23,7 @@ func newUserRepo(conn executor) *userRepo {
|
||||
}
|
||||
|
||||
func (c *userRepo) GetByMemberID(memberID string) (entity.User, error) {
|
||||
finalQuery := c.getQuery() + " AND a.member = ? AND e.key = 'US'"
|
||||
finalQuery := c.getQuery() + " AND a.subscriber_id = ? AND e.key = 'US'"
|
||||
|
||||
user, err := c.parseSet(c.conn.Query(finalQuery, memberID))
|
||||
if err != nil {
|
||||
@@ -192,7 +192,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)
|
||||
&workAddress.ID, &workAddress.UUID, &workAddress.AddressType.ID, &workAddress.AddressType.Key, &workAddress.AddressType.Name, &workAddress.Name, &workAddress.Address, &workAddress.Latitude, &workAddress.Longitude, &retVal.Type)
|
||||
if err != nil {
|
||||
if err != sql.ErrNoRows {
|
||||
return retVal, errors.Wrap(err)
|
||||
@@ -230,7 +230,7 @@ func (c *userRepo) getQuery() string {
|
||||
a.user_id,
|
||||
a.user_uuid,
|
||||
a.name,
|
||||
IFNULL(a.member, '') member,
|
||||
IFNULL(a.subscriber_id, '') subscriber_id,
|
||||
a.birth_date,
|
||||
b.login_id,
|
||||
b.login_uuid,
|
||||
@@ -260,24 +260,25 @@ 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(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
|
||||
FROM
|
||||
tab_user a
|
||||
INNER JOIN
|
||||
@@ -521,7 +522,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.member, '') = ?;", u.Member))
|
||||
users, err := c.parseSet(c.conn.Query(c.getQuery()+" AND a.active = 1 AND e.key = 'US' AND IFNULL(a.subscriber_id, '') = ?;", u.Member))
|
||||
if err != nil {
|
||||
return user, errors.Wrap(err)
|
||||
}
|
||||
@@ -586,11 +587,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`, member, birth_date, gender) VALUES(?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE user_uuid = ?, `name` = ?, member = ?, birth_date = ?, gender = ?;"
|
||||
query = "INSERT INTO tab_user(user_uuid, `name`, subscriber_id, birth_date, gender, member_type, user_hash) VALUES(?, ?, ?, ?, ?, ?, SHA2(CONCAT_WS('-',?,?,?,?,?), 512)) ON DUPLICATE KEY UPDATE user_uuid = ?, `name` = ?, subscriber_id = ?, 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), guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender))
|
||||
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, guid.String(), user.Name, toNullString(user.Member), toNullTime(user.BirthDate), toNullString(user.Gender))
|
||||
if err != nil {
|
||||
return 0, "", err
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (c *visitRepo) getQuery() string {
|
||||
a.user_id,
|
||||
c.user_uuid,
|
||||
c.name user_name,
|
||||
c.member user_member,
|
||||
c.subscriber_id user_member,
|
||||
c.birth_date user_birth_date,
|
||||
c.gender user_gender,
|
||||
a.visit_datetime,
|
||||
@@ -78,7 +78,7 @@ 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,
|
||||
|
||||
@@ -62,4 +62,4 @@ func (c *zipcodeRepo) GetAll() ([]entity.Zipcode, error) {
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ type User struct {
|
||||
Profiles []Profile `json:"profiles,omitempty"`
|
||||
Types []OrganizationType `json:"types,omitempty"`
|
||||
Organizations []Organization `json:"organizations,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
type ContactInfo struct {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
|
||||
)
|
||||
|
||||
@@ -20,11 +22,13 @@ 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
|
||||
}
|
||||
|
||||
@@ -58,6 +62,8 @@ func (s *rideService) GetByID(id int64, user entity.User) (entity.Ride, error) {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"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"
|
||||
"googlemaps.github.io/maps"
|
||||
)
|
||||
@@ -77,6 +78,10 @@ func (c *controller) handleEligibility(ctx echo.Context) error {
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
|
||||
if validationErrors := validation.ValidateEligibility(&eligibility.User); len(validationErrors) > 0 {
|
||||
return routeutils.ResponseAPICustomValidationError(ctx, "eligibility validation failed", validationErrors)
|
||||
}
|
||||
|
||||
if eligibility.Provider.ProviderNPI == "" {
|
||||
provider, err := c.svc.Provider.GetByOrganization(authUser.Profiles[0].Organization.UUID, authUser)
|
||||
if err != nil {
|
||||
|
||||
@@ -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,11 +92,12 @@ func ResponseAPINotFoundError(c echo.Context) error {
|
||||
return ResponseAPIError(c, http.StatusNotFound, "Not Found", false)
|
||||
}
|
||||
|
||||
//ResponseAPINotEligible returns a standard API not eligible to the response
|
||||
//ResponseAPINotEligibleError returns a standard API not eligible to the response
|
||||
func ResponseAPINotEligibleError(c echo.Context) error {
|
||||
return ResponseAPIError(c, http.StatusForbidden, "Eligibility Not Found or Error", false)
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package selfregisterroute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
b64 "encoding/base64"
|
||||
@@ -16,6 +17,16 @@ import (
|
||||
"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
|
||||
@@ -38,55 +49,53 @@ func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *co
|
||||
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)
|
||||
}
|
||||
|
||||
if user.PhoneNumber == nil || len(*user.PhoneNumber) == 0 {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "phonenumber is required")
|
||||
}
|
||||
|
||||
if user.Email == nil || len(*user.Email) == 0 {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "email is required")
|
||||
}
|
||||
|
||||
if len(user.Pass) == 0 {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "password is required")
|
||||
}
|
||||
|
||||
pass, err := b64.StdEncoding.DecodeString(user.Pass)
|
||||
if err != nil {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "Invalid password")
|
||||
}
|
||||
user.Pass = string(pass)
|
||||
|
||||
if passwordValidationErrors := validation.ValidatePassword(&user); len(passwordValidationErrors) > 0 {
|
||||
return routeutils.ResponseAPICustomValidationError(ctx, "Password not strong enough", passwordValidationErrors)
|
||||
}
|
||||
|
||||
if len(user.Name) == 0 && len(user.First) == 0 && len(user.Last) == 0 {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "name is required")
|
||||
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)
|
||||
}
|
||||
|
||||
if len(user.Provider.InternalID) == 0 || len(user.Provider.InternalID) > 10 {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "Provider NPI is invalid")
|
||||
}
|
||||
|
||||
if len(user.Provider.OrganizatioName) == 0 {
|
||||
return routeutils.ResponseAPIValidationError(ctx, "Provider Organization Name is invalid")
|
||||
}
|
||||
|
||||
provider, err := c.svc.Provider.GetByNPI(user.Provider.InternalID, authUser)
|
||||
if err != nil {
|
||||
fmt.Println("Error to create organization", err)
|
||||
@@ -139,5 +148,36 @@ func (c *controller) handle(ctx echo.Context) error {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -239,6 +239,42 @@ 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]
|
||||
@@ -304,14 +340,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.Destination.ID
|
||||
resp.Origin.ID = requestRide.Provider.MukID
|
||||
resp.Destination.Name = requestRide.Origin.Name
|
||||
resp.Destination.ID = requestRide.Origin.ID
|
||||
} else {
|
||||
resp.Origin.Name = requestRide.Origin.Name
|
||||
resp.Origin.ID = requestRide.Origin.ID
|
||||
resp.Destination.Name = requestRide.Destination.Name
|
||||
resp.Destination.ID = requestRide.Destination.ID
|
||||
resp.Destination.ID = requestRide.Provider.MukID
|
||||
}
|
||||
|
||||
resp.Distance = requestRide.Distance
|
||||
@@ -338,6 +374,7 @@ 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)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package usersroute
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
b64 "encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"bytes"
|
||||
"strings"
|
||||
|
||||
"bitbucket.org/nemt/nemt-portal-api/application/applicationservice"
|
||||
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi"
|
||||
@@ -19,8 +19,8 @@ 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/validation"
|
||||
"bitbucket.org/nemt/nemt-portal-api/server/router/routeutils"
|
||||
"bitbucket.org/nemt/nemt-portal-api/server/validation"
|
||||
"github.com/labstack/echo"
|
||||
"golang.org/x/net/context"
|
||||
"googlemaps.github.io/maps"
|
||||
@@ -346,7 +346,7 @@ func (c *controller) handleMember(ctx echo.Context) error {
|
||||
}
|
||||
|
||||
//Validate member
|
||||
if validationErrors := validation.ValidateEligibility(&user) ; len(validationErrors) > 0 {
|
||||
if validationErrors := validation.ValidateEligibility(&user); len(validationErrors) > 0 {
|
||||
return routeutils.ResponseAPICustomValidationError(ctx, "eligibility validation failed", validationErrors)
|
||||
}
|
||||
|
||||
@@ -409,44 +409,44 @@ func (c *controller) handleMember(ctx echo.Context) error {
|
||||
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
|
||||
|
||||
/*
|
||||
resp, err := c.bcbsi.BXE.Get271(eligibility)
|
||||
if err != nil {
|
||||
fmt.Println("Eligibility Not Found or Error: ", err.Error())
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
resp, err := c.bcbsi.BXE.Get271(eligibility)
|
||||
if err != nil {
|
||||
fmt.Println("Eligibility Not Found or Error: ", err.Error())
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
*/
|
||||
|
||||
//This part is emulating eligibility check for testing purposes
|
||||
client := &http.Client{}
|
||||
eligibilityJson, err := json.Marshal(eligibility)
|
||||
if err != nil {
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
req, _ := http.NewRequest("POST", c.cfg.Eligibility.Url, bytes.NewBuffer(eligibilityJson))
|
||||
req.Header.Add("App", c.cfg.HTTP.Auth.AppKey)
|
||||
req.Header.Add("Token", ctx.Request().Header.Get("Token"))
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 300 {
|
||||
return routeutils.ResponseAPINotEligibleWithMessageError(ctx, "Cannot check eligibility")
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
|
||||
eligibilityResponse := viewmodel.Interchange271{}
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
err = decoder.Decode(&eligibilityResponse)
|
||||
if err != nil {
|
||||
return routeutils.ResponseAPINotEligibleWithMessageError(ctx, "Cannot check eligibility")
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
//================================================================
|
||||
|
||||
if len(eligibilityResponse.Division.HealthCareEligibilityResponse.LoopHL0030) < 1 {
|
||||
return routeutils.ResponseAPINotEligibleWithMessageError(ctx, "Cannot check eligibility")
|
||||
return routeutils.ResponseAPINotEligibleError(ctx)
|
||||
}
|
||||
|
||||
address := viewmodel.Address{}
|
||||
@@ -467,17 +467,17 @@ func (c *controller) handleMember(ctx echo.Context) error {
|
||||
if len(cleanZipcode) > zipcodeTrimLength {
|
||||
trimmedZipcode = cleanZipcode[:zipcodeTrimLength]
|
||||
}
|
||||
|
||||
|
||||
_, err = c.svc.Zipcodes.GetByParticipatingZipcode(trimmedZipcode)
|
||||
|
||||
if err != nil{
|
||||
return routeutils.ResponseAPINotEligibleWithMessageError(ctx, "Member's Home zipcode, " + trimmedZipcode + ", is not currently eligible for participation in this program")
|
||||
if err != nil {
|
||||
return routeutils.ResponseAPINotEligibleWithMessageError(ctx, "Member's Home zipcode, "+trimmedZipcode+", is not currently eligible for participation in this program")
|
||||
}
|
||||
|
||||
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.HandleAPIError(ctx,err)
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
|
||||
r := &maps.GeocodingRequest{
|
||||
@@ -487,7 +487,7 @@ func (c *controller) handleMember(ctx echo.Context) error {
|
||||
result, err := googleMapsAPI.Geocode(context.Background(), r)
|
||||
if err != nil {
|
||||
fmt.Println("Error to instantiate googles api: ", err.Error())
|
||||
return routeutils.HandleAPIError(ctx,err)
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
|
||||
if len(result) > 0 {
|
||||
@@ -497,7 +497,7 @@ func (c *controller) handleMember(ctx echo.Context) error {
|
||||
_, err := c.svc.Users.SaveAddress(address)
|
||||
if err != nil {
|
||||
fmt.Println("Error to save address: ", err.Error())
|
||||
return routeutils.HandleAPIError(ctx,err)
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,7 +597,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)
|
||||
}
|
||||
|
||||
|
||||
@@ -88,9 +88,14 @@ func (c *controller) handleRide(ctx echo.Context) error {
|
||||
fmt.Println(err)
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
user.PhoneNumber = ride.User.PhoneNumber
|
||||
user.Email = ride.User.Email
|
||||
|
||||
ride.Visit.User = user
|
||||
subscriber := "S"
|
||||
ride.Visit.User.Type = &subscriber
|
||||
if ride.Visit.User.Type == nil {
|
||||
subscriber := "S"
|
||||
ride.Visit.User.Type = &subscriber
|
||||
}
|
||||
|
||||
var provider viewmodel.ProviderResp
|
||||
provider, err = c.svc.Provider.GetByUUID(ride.Visit.Provider.ProviderUUID, authUser)
|
||||
@@ -189,13 +194,17 @@ func (c *controller) handleRide(ctx echo.Context) error {
|
||||
Longitude: visit.Provider.Address.Longitude,
|
||||
Address: visit.Provider.Address.StreetAddress1,
|
||||
}
|
||||
ride.Origin = viewmodel.Location{
|
||||
ID: homeAddress.UUID,
|
||||
Name: homeAddress.AddressTypeName,
|
||||
Latitude: homeAddress.Latitude,
|
||||
Longitude: homeAddress.Longitude,
|
||||
Address: homeAddress.Address,
|
||||
|
||||
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 = " "
|
||||
@@ -203,6 +212,11 @@ func (c *controller) handleRide(ctx echo.Context) error {
|
||||
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" {
|
||||
@@ -457,25 +471,25 @@ func (c *controller) handle(ctx echo.Context) error {
|
||||
return routeutils.ResponseAPICustomValidationError(ctx, "visit validation failed", validationErrors)
|
||||
}
|
||||
|
||||
// eligibility := viewmodel.Eligibility{}
|
||||
// eligibility.Provider.ProviderNPI = provider.InternalID
|
||||
// eligibility.Provider.ProviderName = provider.OrganizatioName
|
||||
// eligibility.TrackingID = c.rangeIn(1000000, 9999999)
|
||||
// eligibility.Subscriber.SubscriberID = *visit.User.Member
|
||||
// eligibility.Subscriber.PatientType = *visit.User.Type
|
||||
// eligibility.Subscriber.Name.First = visit.User.First
|
||||
// eligibility.Subscriber.Name.Last = visit.User.Last
|
||||
// eligibility.Subscriber.DemographicInfo.DateOfBirth = *visit.User.BirthDate
|
||||
// eligibility.Subscriber.DemographicInfo.Gender = *visit.User.Gender
|
||||
// loc, _ := time.LoadLocation("America/Chicago")
|
||||
// eligibility.ServiceInfo.DateOfService = time.Now().In(loc)
|
||||
// eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
|
||||
eligibility := viewmodel.Eligibility{}
|
||||
eligibility.Provider.ProviderNPI = provider.InternalID
|
||||
eligibility.Provider.ProviderName = provider.OrganizatioName
|
||||
eligibility.TrackingID = c.rangeIn(1000000, 9999999)
|
||||
eligibility.Subscriber.SubscriberID = *visit.User.Member
|
||||
eligibility.Subscriber.PatientType = *visit.User.Type
|
||||
eligibility.Subscriber.Name.First = visit.User.First
|
||||
eligibility.Subscriber.Name.Last = visit.User.Last
|
||||
eligibility.Subscriber.DemographicInfo.DateOfBirth = *visit.User.BirthDate
|
||||
eligibility.Subscriber.DemographicInfo.Gender = *visit.User.Gender
|
||||
loc, _ := time.LoadLocation("America/Chicago")
|
||||
eligibility.ServiceInfo.DateOfService = time.Now().In(loc)
|
||||
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
|
||||
|
||||
// resp, err := c.bcbsi.BXE.Get271(eligibility)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error to get eligibility: ", err.Error())
|
||||
// return routeutils.ResponseAPIValidationError(ctx, err.Error())
|
||||
// }
|
||||
resp, err := c.bcbsi.BXE.Get271(eligibility)
|
||||
if err != nil {
|
||||
fmt.Println("Error to get eligibility: ", err.Error())
|
||||
return routeutils.ResponseAPIValidationError(ctx, err.Error())
|
||||
}
|
||||
|
||||
user, err := c.svc.Users.GetByMemberID(*visit.User.Member)
|
||||
if err != nil {
|
||||
@@ -551,60 +565,60 @@ func (c *controller) handle(ctx echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// zipCode := strings.TrimSpace(body.N403)
|
||||
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
|
||||
zipCode := strings.TrimSpace(body.N403)
|
||||
|
||||
// address.AddressTypeName = "Home"
|
||||
// address.AddressType = "home"
|
||||
// address.Name = fmt.Sprintf("%s, %s", header.N301, body.N401)
|
||||
// address.Address = fmt.Sprintf("%s, %s (%s)", header.N301, body.N401, zipCode)
|
||||
// address.CreatedUserUUID = authUser.ID
|
||||
// address.User = user
|
||||
// address.Type = "provider"
|
||||
address.AddressTypeName = "Home"
|
||||
address.AddressType = "home"
|
||||
address.Name = fmt.Sprintf("%s, %s", header.N301, body.N401)
|
||||
address.Address = fmt.Sprintf("%s, %s (%s)", header.N301, body.N401, zipCode)
|
||||
address.CreatedUserUUID = authUser.ID
|
||||
address.User = user
|
||||
address.Type = "provider"
|
||||
|
||||
// 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.HandleAPIError(ctx, err)
|
||||
// }
|
||||
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.HandleAPIError(ctx, err)
|
||||
}
|
||||
|
||||
// r := &maps.GeocodingRequest{
|
||||
// Address: address.Address + " " + body.N402 + ", " + zipCode,
|
||||
// }
|
||||
r := &maps.GeocodingRequest{
|
||||
Address: address.Address + " " + body.N402 + ", " + zipCode,
|
||||
}
|
||||
|
||||
// result, err := googleMapsAPI.Geocode(context.Background(), r)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error to instantiate googles api: ", err.Error())
|
||||
// return routeutils.HandleAPIError(ctx, err)
|
||||
// }
|
||||
result, err := googleMapsAPI.Geocode(context.Background(), r)
|
||||
if err != nil {
|
||||
fmt.Println("Error to instantiate googles api: ", err.Error())
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
|
||||
// if len(result) > 0 {
|
||||
// address.Latitude = result[0].Geometry.Location.Lat
|
||||
// address.Longitude = result[0].Geometry.Location.Lng
|
||||
// }
|
||||
if len(result) > 0 {
|
||||
address.Latitude = result[0].Geometry.Location.Lat
|
||||
address.Longitude = result[0].Geometry.Location.Lng
|
||||
}
|
||||
|
||||
// if address.Latitude != 0 && address.Longitude != 0 {
|
||||
// if len(user.Addresses) > 0 {
|
||||
// for _, a := range user.Addresses {
|
||||
// if a.AddressType == "home" {
|
||||
// err := c.svc.Users.RemoveAddress(a.UUID)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error to remove old address: ", err.Error())
|
||||
// return routeutils.HandleAPIError(ctx, err)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if address.Latitude != 0 && address.Longitude != 0 {
|
||||
if len(user.Addresses) > 0 {
|
||||
for _, a := range user.Addresses {
|
||||
if a.AddressType == "home" {
|
||||
err := c.svc.Users.RemoveAddress(a.UUID)
|
||||
if err != nil {
|
||||
fmt.Println("Error to remove old address: ", err.Error())
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// address, err = c.svc.Users.SaveAddress(address)
|
||||
// if err != nil {
|
||||
// fmt.Println("Error saving address: ", err.Error())
|
||||
// return routeutils.HandleAPIError(ctx, err)
|
||||
// }
|
||||
// user.Addresses = append(user.Addresses, address)
|
||||
// }
|
||||
address, err = c.svc.Users.SaveAddress(address)
|
||||
if err != nil {
|
||||
fmt.Println("Error saving address: ", err.Error())
|
||||
return routeutils.HandleAPIError(ctx, err)
|
||||
}
|
||||
user.Addresses = append(user.Addresses, address)
|
||||
}
|
||||
|
||||
visit.TripType = viewmodel.TripType{
|
||||
Key: "no_trip",
|
||||
|
||||
@@ -9,21 +9,21 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
firstNameMaxLength = 50
|
||||
lastNameMaxLength = 50
|
||||
emailMaxLength = 150
|
||||
firstNameMaxLength = 50
|
||||
lastNameMaxLength = 50
|
||||
emailMaxLength = 150
|
||||
|
||||
memberNumberValidNumberOfLetters = 3
|
||||
memberNumberValidNumberOfLetters = 3
|
||||
)
|
||||
|
||||
const (
|
||||
formModeVisit = 1
|
||||
formModeRide = 2
|
||||
formModeVisit = 1
|
||||
formModeRide = 2
|
||||
)
|
||||
|
||||
func isAlphabetic(input string) bool {
|
||||
for _, character := range input {
|
||||
if !(characterIsUpperCase(character) || characterIsLowerCase(character)){
|
||||
if !(characterIsUpperCase(character) || characterIsLowerCase(character)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ func isAlphabetic(input string) bool {
|
||||
|
||||
func isNumeric(input string) bool {
|
||||
for _, character := range input {
|
||||
if !characterIsNumber(character){
|
||||
if !characterIsNumber(character) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ func isNumeric(input string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isEmailValid (email string) bool {
|
||||
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)
|
||||
@@ -55,7 +55,7 @@ func isMemberNumberValid(input string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if !isNumeric(input[memberNumberValidNumberOfLetters:]){
|
||||
if !isNumeric(input[memberNumberValidNumberOfLetters:]) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -65,19 +65,19 @@ func isMemberNumberValid(input string) bool {
|
||||
func ValidateEligibility(user *viewmodel.User) []errors.ValidationError {
|
||||
var result []errors.ValidationError
|
||||
|
||||
formMode:= formModeVisit // This should be red from request, not hardcoded
|
||||
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){
|
||||
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"})
|
||||
result = append(result, errors.ValidationError{Field: "first", Message: "First Name is too long"})
|
||||
}
|
||||
|
||||
//Last name validation
|
||||
@@ -85,66 +85,66 @@ func ValidateEligibility(user *viewmodel.User) []errors.ValidationError {
|
||||
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is required"})
|
||||
}
|
||||
|
||||
if !isAlphabetic(user.Last){
|
||||
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"})
|
||||
result = append(result, errors.ValidationError{Field: "last", Message: "Last Name is too long"})
|
||||
}
|
||||
|
||||
//Email validation
|
||||
if user.Email != nil {
|
||||
if (formMode==formModeRide) && len(*user.Email) < 1 {
|
||||
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){
|
||||
} 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"})
|
||||
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"})
|
||||
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"})
|
||||
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)
|
||||
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"})
|
||||
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"})
|
||||
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'"})
|
||||
if !user.Consent {
|
||||
result = append(result, errors.ValidationError{Field: "consent", Message: "Must be 'Checked'"})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
111
server/validation/selfregister.go
Normal file
111
server/validation/selfregister.go
Normal file
@@ -0,0 +1,111 @@
|
||||
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
|
||||
}
|
||||
@@ -1,36 +1,34 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
|
||||
"time"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"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_call"
|
||||
tripTypeRoundTrip = "roundtrip"
|
||||
tripTypeRountTripWillCall = "roundtrip_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 {
|
||||
@@ -38,7 +36,7 @@ func isMixedIDValid(id string) bool {
|
||||
hasLowerCase := false
|
||||
hasNumber := false
|
||||
|
||||
for _, character := range (id) {
|
||||
for _, character := range id {
|
||||
hasUpperCase = hasUpperCase || ((character >= 65) && (character <= 90))
|
||||
hasLowerCase = hasLowerCase || ((character >= 97) && (character <= 122))
|
||||
hasNumber = hasNumber || ((character >= 48) && (character <= 57))
|
||||
@@ -47,169 +45,185 @@ func isMixedIDValid(id string) bool {
|
||||
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 !validUUIDregex.MatchString(user.ID) {
|
||||
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 {
|
||||
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"})
|
||||
}
|
||||
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)
|
||||
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 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"})
|
||||
}
|
||||
|
||||
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"})
|
||||
}
|
||||
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"})
|
||||
}
|
||||
|
||||
case tripTypeFromVisitWillCall:
|
||||
//no special validation for this case
|
||||
if isVisitDayToday && requestRide.PickupTime.Before(before8Hours) {
|
||||
result = append(result, errors.ValidationError{Field: "pickup_time", Message: "Step #4 - Visit cannot occour in the past"})
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
}
|
||||
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.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"})
|
||||
}
|
||||
}
|
||||
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"})
|
||||
}
|
||||
|
||||
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 "})
|
||||
}
|
||||
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"})
|
||||
}
|
||||
|
||||
default:
|
||||
isTripTypeValid = false
|
||||
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 !isTripTypeValid {
|
||||
result = append (result, errors.ValidationError{Field : "trip_type.key", Message : "Step #4 - Choose a Trip Type"})
|
||||
result = append(result, errors.ValidationError{Field: "trip_type.key", Message: "Step #4 - Choose a Trip Type"})
|
||||
}
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
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
|
||||
|
||||
if len(visit.User.First) == 0 {
|
||||
result = append(result, errors.ValidationError{Field: "first", Message: "Step #1 - First Name is mandatory"})
|
||||
// Step #1
|
||||
if len(visit.Provider.ProviderUUID) == 0 {
|
||||
result = append(result, errors.ValidationError{Field: "provider.id", Message: "Step #1 - Provider is required"})
|
||||
}
|
||||
|
||||
if len(visit.User.Last) == 0 {
|
||||
result = append(result, errors.ValidationError{Field: "last", Message: "Step #1 - Last Name is mandatory"})
|
||||
// Step #2
|
||||
eligibilityResult := ValidateEligibility(&visit.User)
|
||||
if len(eligibilityResult) > 0 {
|
||||
result = append(result, eligibilityResult...)
|
||||
}
|
||||
|
||||
if visit.User.Gender == nil || (*visit.User.Gender != "M" && *visit.User.Gender != "F" && *visit.User.Gender != "U") {
|
||||
result = append(result, errors.ValidationError{Field: "gender", Message: "Step #1 - Gender is mandatory"})
|
||||
}
|
||||
//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"})
|
||||
}
|
||||
|
||||
if visit.User.Type == nil || (*visit.User.Type != "S" && *visit.User.Gender != "D" && *visit.User.Gender != "U") {
|
||||
result = append(result, errors.ValidationError{Field: "type", Message: "Step #1 - Member Type is mandatory"})
|
||||
}
|
||||
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 visit.User.Member == nil || len(*visit.User.Member) == 0 {
|
||||
result = append(result, errors.ValidationError{Field: "member", Message: "Step #1 - Member # is mandatory"})
|
||||
}
|
||||
|
||||
if visit.User.BirthDate == nil || visit.User.BirthDate.IsZero() {
|
||||
result = append(result, errors.ValidationError{Field: "birthdate", Message: "Step #1 - Birth Date is mandatory"})
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user