Upstream sync

This commit is contained in:
Senad Uka
2018-05-25 09:12:42 +02:00
parent 6e903b4d57
commit 94229831e0
38 changed files with 1281 additions and 156 deletions

View File

@@ -1,6 +1,7 @@
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/

View File

@@ -23,7 +23,8 @@ type Service struct {
Notification *notificationService
Profile *profileService
Organization *organizationService
Zipcodes *zipcodeService
Zipcodes *zipcodeService
Plan *planService
}
// New returns a new domain Service instance
@@ -37,7 +38,8 @@ func New(svc *service.Service, mapper *entitymapping.Mapper, notification *notif
Notification: newNotificationService(svc, mapper, notification, cfg),
Profile: newProfileService(svc, mapper),
Organization: newOrganizationService(svc, mapper),
Zipcodes: newZipcodeService(svc, mapper),
Zipcodes: newZipcodeService(svc, mapper),
Plan: newPlanService(svc, mapper),
}
})

View File

@@ -0,0 +1,57 @@
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

@@ -68,3 +68,13 @@ func (s *providerService) GetByNPI(NPI string, user viewmodel.User) (viewmodel.P
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

@@ -51,6 +51,16 @@ 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
}
// 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)
@@ -131,6 +141,11 @@ 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)

View File

@@ -21,6 +21,38 @@ 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 {
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 {
return viewmodel.Visit{}, errors.Wrap(err)
}
entity.Provider = provider
retVal, err := s.svc.Visits.Create(entity)
if err != nil {
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)
@@ -51,5 +83,17 @@ func (s *visitService) GetByUUID(visitUUID string, user viewmodel.User) (viewmod
return viewmodel.Visit{}, errors.Wrap(err)
}
visitUser, err := s.svc.Users.GetByUUID(retVal.User.UUID, "US")
if err != nil {
return viewmodel.Visit{}, errors.Wrap(err)
}
retVal.User = visitUser
provider, err := s.svc.Provider.GetByUUID(retVal.Provider.ProviderUUID, eUser)
if err != nil {
return viewmodel.Visit{}, errors.Wrap(err)
}
retVal.Provider = provider
return s.mapEntity.Visit.ToVisitModel(retVal), err
}

View File

@@ -21,7 +21,8 @@ type Mapper struct {
Notification *notificationMapping
Profile *profileMapping
Organization *organizationMapping
Zipcode *zipcodeMapping
Zipcode *zipcodeMapping
Plan *planMapping
}
// New returns an EntityMapper for fluent mapping
@@ -38,6 +39,7 @@ func New() *Mapper {
instance.Profile = &profileMapping{instance}
instance.Organization = &organizationMapping{instance}
instance.Zipcode = &zipcodeMapping{instance}
instance.Plan = &planMapping{instance}
})
return instance

View File

@@ -0,0 +1,65 @@
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

@@ -80,6 +80,8 @@ func (s bxeService) Get271(eligibility viewmodel.Eligibility) (bcbsimodel.Interc
return bcbsimodel.Interchange271{}, err
}
fmt.Println(resp)
if resp.QueryResult.HIPPA271.T271 != "" {
xmlString := html.UnescapeString(resp.QueryResult.HIPPA271.T271)
xmlReader := strings.NewReader(xmlString)
@@ -98,13 +100,10 @@ func (s bxeService) Get271(eligibility viewmodel.Eligibility) (bcbsimodel.Interc
}
func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimodel.MemberEligibilityResponse, error) {
// 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"
if eligibility.Payer.PayerID == "" || eligibility.Payer.PayerName == "" {
eligibility.Payer.PayerID = "621"
eligibility.Payer.PayerName = "blue_cross_blue_shield_il"
}
envelope := bcbsimodel.GetEnvelope(eligibility)
apiKey := s.cfg.BXE.APIKey
@@ -146,7 +145,6 @@ func (s bxeService) CheckEligibility(eligibility viewmodel.Eligibility) (bcbsimo
fmt.Println("Error WebService getting object: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
fmt.Println("Result: ", result.Body.MemberEligibilityResponse)
return result.Body.MemberEligibilityResponse, nil
}

View File

@@ -11,6 +11,7 @@ type Eligibility struct {
Provider Provider `json:"provider,omitempty"`
Subscriber Subscriber `json:"subscriber,omitempty"`
ServiceInfo ServiceInfo `json:"service_info,omitempty"`
User User `json:"user,omitempty"`
}
type Payer struct {

View File

@@ -0,0 +1,15 @@
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

@@ -18,6 +18,7 @@ pipelines:
- 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
@@ -49,6 +50,7 @@ pipelines:
- 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

View File

@@ -1,41 +1,41 @@
-----BEGIN CERTIFICATE-----
MIIGvjCCBaagAwIBAgIQC3nVkJVbuOa1WFfJQc+IMDANBgkqhkiG9w0BAQsFADBN
MIIGxzCCBa+gAwIBAgIQDARDXxHDhGyEB0wVou2tYTANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTgwNTIxMDAwMDAwWhcN
MjAwNTIwMTIwMDAwWjCBhTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz
MjAwNTIwMTIwMDAwWjCBgTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lz
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=
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

View File

@@ -28,7 +28,8 @@ type Conn struct {
notification *notificationRepo
profile *profileRepo
organization *organizationRepo
zipcodes *zipcodeRepo
zipcodes *zipcodeRepo
plan *planRepo
}
// Begin starts a transaction
@@ -81,10 +82,14 @@ func (c *Conn) Organization() contract.OrganizationRepo {
return c.organization
}
func (c *Conn) Zipcodes() contract.ZipcodeRepo{
func (c *Conn) Zipcodes() contract.ZipcodeRepo {
return c.zipcodes
}
func (c *Conn) Plans() contract.PlanRepo {
return c.plan
}
// Instance returns an instance of a DataManager
func Instance(cfg *config.Config) (contract.DataManager, error) {
once.Do(func() {
@@ -117,6 +122,7 @@ func Instance(cfg *config.Config) (contract.DataManager, error) {
instance.profile = newProfileRepo(db)
instance.organization = newOrganizationRepo(db)
instance.zipcodes = newZipcodeRepo(db)
instance.plan = newPlanRepo(db)
})
return instance, connErr

View File

@@ -44,7 +44,7 @@ func (c *organizationRepo) getProfileQuery(user entity.User) (query string, wher
where = fmt.Sprintf(` AND (a.organization_uuid = '%s' OR f.organization_uuid = '%s') `, p.Organization.UUID, p.Organization.UUID)
return
}
case "SP", "SPT":
case "SP", "SPT", "VIRPT":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa":
return

82
data/datamysql/plan.go Normal file
View File

@@ -0,0 +1,82 @@
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":
case "AD", "BCBSIAD", "BDCAD", "PLANAD", "VIRPT":
return
case "SP", "SPT":
switch p.Organization.Type.Key {
@@ -145,6 +145,20 @@ func (c *providerRepo) GetByUUID(providerUUID string, user entity.User) (entity.
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

View File

@@ -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":
case "SP", "SPT", "VIRPT":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa", "plan":
return
case "provider":
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)
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)
return
}
}
@@ -676,6 +676,7 @@ 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

@@ -16,7 +16,8 @@ type transaction struct {
notification *notificationRepo
profile *profileRepo
organization *organizationRepo
zipcodes *zipcodeRepo
zipcodes *zipcodeRepo
plan *planRepo
}
func newTransaction(tx *sql.Tx) *transaction {
@@ -28,6 +29,11 @@ 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)
return t
}
@@ -67,10 +73,14 @@ func (t transaction) Organization() contract.OrganizationRepo {
return t.organization
}
func (t transaction) Zipcodes() contract.ZipcodeRepo{
func (t transaction) Zipcodes() contract.ZipcodeRepo {
return t.zipcodes
}
func (t transaction) Plans() contract.PlanRepo {
return t.plan
}
func (t *transaction) Commit() error {
err := t.tx.Commit()

View File

@@ -22,6 +22,32 @@ func newUserRepo(conn executor) *userRepo {
}
}
func (c *userRepo) GetByMemberID(memberID string) (entity.User, error) {
finalQuery := c.getQuery() + " AND a.member = ? 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) GetByUUID(uuid string, profile string) (entity.User, error) {
params := make([]interface{}, 0)
params = append(params, uuid)
@@ -390,6 +416,24 @@ 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 = ?;`
@@ -561,7 +605,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 = "DELETE FROM tab_address WHERE address_uuid = ?;"
)
_, err := c.conn.Exec(query, addressUUID)

View File

@@ -27,14 +27,13 @@ func (c *visitRepo) getProfileQuery(user entity.User) (query string, where strin
switch p.Key {
case "AD", "BCBSIAD", "BDCAD", "PLANAD":
return
case "SP", "SPT":
case "SP", "SPT", "VIRPT":
switch p.Organization.Type.Key {
case "techsupport", "bcbsi", "bcbsa", "plan":
return
case "provider":
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)
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)
return
}
}
@@ -85,17 +84,17 @@ func (c *visitRepo) getQuery() string {
IFNULL(f.provider_muk_id, '') provider_muk_id,
IFNULL(f.provider_name, '') provider_name
FROM
tab_visit a
INNER JOIN tab_visit_status b
tab_visit AS a
INNER JOIN tab_visit_status AS b
ON a.visit_status_id = b.visit_status_id
INNER JOIN tab_user c
INNER JOIN tab_user AS c
ON c.user_id = a.user_id
INNER JOIN tab_user d
INNER JOIN tab_user AS d
ON d.user_id = a.created_user_id
INNER JOIN tab_trip_type e
INNER JOIN tab_trip_type AS e
ON e.trip_type_id = a.trip_type_id
INNER JOIN tab_provider f
ON f.provider_id = a.provider_id `
INNER JOIN tab_provider AS f
ON f.provider_id = a.provider_id `
}
func (c *visitRepo) GetAll(user entity.User) ([]entity.Visit, error) {
@@ -205,6 +204,5 @@ func (c *visitRepo) Create(visit entity.Visit) (entity.Visit, error) {
return retVal, err
}
fmt.Println("Visit ID: ", retVal.ID)
return retVal, nil
}

View File

@@ -3,20 +3,6 @@ map $http_upgrade $connection_upgrade {
'' close;
}
server {
listen 80;
server_name portal-api.dev.bcbinstitute.com;
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;
}
}
server {
listen 443;
ssl on;

View File

@@ -3,20 +3,6 @@ map $http_upgrade $connection_upgrade {
'' close;
}
server {
listen 80;
server_name portal-api.bcbinstitute.com;
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;
}
}
server {
listen 443;
ssl on;

View File

@@ -3,20 +3,6 @@ map $http_upgrade $connection_upgrade {
'' close;
}
server {
listen 80;
server_name portal-api.dev.bcbinstitute.com;
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;
}
}
server {
listen 443;
ssl on;

View File

@@ -13,6 +13,7 @@ type repoManager interface {
Profile() ProfileRepo
Organization() OrganizationRepo
Zipcodes() ZipcodeRepo
Plans() PlanRepo
}
// UserRepo defines the data set for users
@@ -20,6 +21,7 @@ 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)
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)
@@ -30,6 +32,7 @@ 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
@@ -59,6 +62,7 @@ type ProviderRepo interface {
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
@@ -94,6 +98,13 @@ 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)

21
domain/entity/plan.go Normal file
View File

@@ -0,0 +1,21 @@
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"`
}

31
domain/service/plan.go Normal file
View File

@@ -0,0 +1,31 @@
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,6 +1,8 @@
package service
import (
"errors"
"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)
@@ -85,3 +87,21 @@ func (s *providerService) GetByNPI(NPI string, user entity.User) (entity.Provide
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
}

View File

@@ -56,7 +56,12 @@ 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) {
return s.svc.db.Rides().GetByUUID(uuid, user)
ride, err := s.svc.db.Rides().GetByUUID(uuid, user)
if err != nil {
return entity.Ride{}, err
}
return ride, nil
}
// GetByUUID return a specific ride

View File

@@ -25,7 +25,8 @@ type Service struct {
Notification *notificationService
Profile *profileService
Organization *organizationService
Zipcodes *zipcodeService
Zipcodes *zipcodeService
Plans *planService
}
// New returns a new domain Service instance
@@ -41,6 +42,7 @@ func New(db contract.DataManager, cache contract.CacheManager, cfg *config.Confi
instance.Profile = newProfileService(instance)
instance.Organization = newOrganizationService(instance)
instance.Zipcodes = newZipcodeService(instance)
instance.Plans = newPlanService(instance)
})
return instance, nil

View File

@@ -33,6 +33,10 @@ 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)
}
// 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)
@@ -68,6 +72,10 @@ 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, err := s.svc.db.Rides().GetAll(user)
if err != nil {
return nil, err
}
rides, _ := 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, err := s.svc.db.Rides().GetByVisitUUID(visitUUID, user)
if err != nil {
return entity.Visit{}, errors.Wrap(err)
}
rides, _ := 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, err := s.svc.db.Rides().GetByVisitUUID(visit.UUID, user)
if err != nil {
return entity.Visit{}, errors.Wrap(err)
}
rides, _ := 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,18 +1,23 @@
package eligibilityroute
import (
"context"
"encoding/xml"
"fmt"
"html"
"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/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"
"googlemaps.github.io/maps"
)
var (
@@ -37,6 +42,29 @@ 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
@@ -44,13 +72,45 @@ func (c *controller) handleEligibility(ctx echo.Context) error {
return routeutils.HandleAPIError(ctx, err)
}
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
if eligibility.Provider.ProviderNPI == "" {
provider, err := c.svc.Provider.GetByOrganization(authUser.Profiles[0].Organization.UUID, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
eligibility.Provider.ProviderNPI = provider.InternalID
eligibility.Provider.ProviderName = provider.OrganizatioName
}
loc, _ := time.LoadLocation("America/Chicago")
eligibility.TrackingID = c.rangeIn(1000000, 9999999)
eligibility.ServiceInfo.DateOfService = time.Now().In(loc)
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
var plan viewmodel.Plan
if eligibility.Subscriber.SubscriberID != "" {
plan, err = c.svc.Plan.GetByAlphaPrefix(eligibility.Subscriber.SubscriberID[:3])
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
eligibility.Payer.PayerID = fmt.Sprintf("%v", plan.PayerID)
eligibility.Payer.PayerName = plan.PayerName
} else {
return routeutils.ResponseAPIFieldValidationError(ctx, "subscriber_id", "member # is required.")
}
ret, err := c.bcbsi.BXE.CheckEligibility(eligibility)
if err != nil {
fmt.Println("Error Here: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
if ret.QueryResult.HIPPA271.T271 != "" {
if ret.QueryResult.QueryResultSummary.BenefitsFound {
xmlString := html.UnescapeString(ret.QueryResult.HIPPA271.T271)
xmlReader := strings.NewReader(xmlString)
@@ -60,8 +120,133 @@ func (c *controller) handleEligibility(ctx echo.Context) error {
fmt.Println("Error to unmarshal: ", err.Error())
}
return ctx.JSON(200, f)
user, err := c.svc.Users.GetByMemberID(eligibility.Subscriber.SubscriberID)
if err != nil {
fmt.Println(err)
return routeutils.HandleAPIError(ctx, err)
}
if user.ID == "" {
user.Pass = c.generatePassword(8)
user.BirthDate = &eligibility.Subscriber.DemographicInfo.DateOfBirth
user.Member = &eligibility.Subscriber.SubscriberID
user.Gender = &eligibility.Subscriber.DemographicInfo.Gender
user.First = eligibility.Subscriber.Name.First
user.Last = eligibility.Subscriber.Name.Last
user.Active = true
user.Type = &eligibility.Subscriber.PatientType
user.PhoneNumber = eligibility.User.PhoneNumber
user.Email = eligibility.User.Email
profile, err := c.svc.Profile.GetByKey("US")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
user.Profiles = append(user.Profiles, profile)
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)
}
if user.PhoneNumber != nil && len(*user.PhoneNumber) == 10 && !strings.Contains(*user.PhoneNumber, "+1") {
phoneNumber := fmt.Sprintf("+1%s", *user.PhoneNumber)
user.PhoneNumber = &phoneNumber
}
user, err = c.svc.Users.Create(user, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
} else {
if eligibility.User.Email != nil && len(*eligibility.User.Email) > 0 {
user.Email = eligibility.User.Email
}
if eligibility.User.PhoneNumber != nil {
if len(*eligibility.User.PhoneNumber) == 10 && !strings.Contains(*eligibility.User.PhoneNumber, "+1") {
phoneNumber := fmt.Sprintf("+1%s", *eligibility.User.PhoneNumber)
eligibility.User.PhoneNumber = &phoneNumber
}
user.PhoneNumber = eligibility.User.PhoneNumber
}
err = c.svc.Users.UpdateLogin(user)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
}
address := viewmodel.Address{}
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)
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)
}
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)
}
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 := 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 to save address: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
user.Addresses = append(user.Addresses, address)
return ctx.JSON(200, user)
} else {
return routeutils.ResponseAPIOK(ctx, ret)
return routeutils.ResponseAPINotEligibleWithMessageError(ctx, "No benefits found for member")
}
}

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 mandatory")
// if err != nil {
// return err
// }
lat, err := routeutils.GetAndValidateFloatQueryParam(ctx, "lat", "latitude is required")
if err != nil {
return err
}
// long, err := routeutils.GetAndValidateFloatQueryParam(ctx, "long", "longitude is mandatory")
// if err != nil {
// return err
// }
long, err := routeutils.GetAndValidateFloatQueryParam(ctx, "long", "longitude is required")
if err != nil {
return err
}
distance, err := routeutils.GetAndValidateIntQueryParam(ctx, "distance", "distance is mandatory")
distance, err := routeutils.GetAndValidateIntQueryParam(ctx, "distance", "distance is required")
if err != nil {
distance = 10
}
limit, err := routeutils.GetAndValidateIntQueryParam(ctx, "limit", "limit is mandatory")
limit, err := routeutils.GetAndValidateIntQueryParam(ctx, "limit", "limit is required")
if err != nil {
limit = 50
}
sortBy, err := routeutils.GetAndValidateStringQueryParam(ctx, "sortby", "limit is mandatory")
sortBy, err := routeutils.GetAndValidateStringQueryParam(ctx, "sortby", "limit is required")
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: 41.819078,
Longitude: -87.623129,
Latitude: lat,
Longitude: long,
Distance: distance,
Limit: limit,
Offset: 0,

View File

@@ -44,7 +44,7 @@ func Register(e *echo.Echo, cfg *config.Config, svc *applicationservice.Service,
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)
visitroute.Register(appGroup.Group("/visits"), cfg, svc, tnc)
providerroute.Register(appGroup.Group("/provider"), cfg, svc)
placesroute.Register(appGroup.Group("/places"), cfg, svc)
profileroute.Register(appGroup.Group("/profile"), cfg, svc)

View File

@@ -230,7 +230,7 @@ func (c *controller) handle(ctx echo.Context) error {
}
//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)
}
@@ -436,7 +436,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 to notify user: ", err.Error())
fmt.Println("Error notifying user: ", err.Error())
}
}()
}

View File

@@ -1,18 +1,26 @@
package visitroute
import (
"context"
"fmt"
"math/rand"
"strings"
"sync"
"time"
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/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"
"googlemaps.github.io/maps"
)
var (
@@ -24,19 +32,383 @@ type controller struct {
svc *applicationservice.Service
cfg *config.Config
bcbsi *bcbsi.Service
tnc *tncservice.Service
}
func controllerInstance(svc *applicationservice.Service, cfg *config.Config) *controller {
func controllerInstance(svc *applicationservice.Service, cfg *config.Config, tnc *tncservice.Service) *controller {
once.Do(func() {
instance = &controller{
svc: svc,
cfg: cfg,
bcbsi: bcbsi.New(cfg),
tnc: tnc,
}
})
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)
}
ride.Visit = visit
user, err := c.svc.Users.GetByMemberID(*visit.User.Member)
if err != nil {
fmt.Println(err)
return routeutils.HandleAPIError(ctx, err)
}
ride.Visit.User = user
subscriber := "S"
ride.Visit.User.Type = &subscriber
var provider viewmodel.ProviderResp
if authUser.Profiles[0].Key == "VIRPT" {
provider, err = c.svc.Provider.GetByOrganization(authUser.Profiles[0].Organization.UUID, authUser)
} else {
provider, err = c.svc.Provider.GetByUUID(ride.Visit.Provider.ProviderUUID, authUser)
}
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
eligibility := viewmodel.Eligibility{}
eligibility.Provider.ProviderNPI = provider.InternalID
eligibility.Provider.ProviderName = provider.OrganizatioName
eligibility.TrackingID = "1234567"
eligibility.Subscriber.SubscriberID = *ride.Visit.User.Member
eligibility.Subscriber.PatientType = *ride.Visit.User.Type
eligibility.Subscriber.Name.First = ride.Visit.User.First
eligibility.Subscriber.Name.Last = ride.Visit.User.Last
eligibility.Subscriber.DemographicInfo.DateOfBirth = *ride.Visit.User.BirthDate
eligibility.Subscriber.DemographicInfo.Gender = *ride.Visit.User.Gender
eligibility.ServiceInfo.DateOfService = time.Now()
eligibility.ServiceInfo.ServiceTypeCodes = []string{"30"}
resp271, err := c.bcbsi.BXE.Get271(eligibility)
if err != nil {
fmt.Println(err)
return routeutils.ResponseAPIValidationError(ctx, err.Error())
}
address := viewmodel.Address{}
header := resp271.Division.HealthCareEligibilityResponse.LoopHL0030[0].HL_0460[0].HL_0890[0].NM1_0920[0].N3_0950
body := resp271.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"
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,
}
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(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 to save address: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
user.Addresses = append(user.Addresses, address)
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,
}
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
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 c.cfg.LyftProd.UserUUID != authUser.ID {
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 c.cfg.LyftProd.UserUUID != authUser.ID {
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 {
@@ -44,25 +416,29 @@ func (c *controller) handle(ctx echo.Context) error {
return routeutils.ResponseAPIValidationError(ctx, "invalid parameters")
}
user, err := auth.GetUserDetail(ctx, c.cfg)
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
provider, err := c.svc.Provider.GetByUUID(visit.Provider.ProviderUUID, user)
var provider viewmodel.ProviderResp
if authUser.Profiles[0].Key == "VIRPT" {
provider, err = c.svc.Provider.GetByOrganization(authUser.Profiles[0].Organization.UUID, authUser)
} else {
provider, err = c.svc.Provider.GetByUUID(visit.Provider.ProviderUUID, authUser)
}
if err != nil {
fmt.Println(err)
return routeutils.ResponseAPIValidationError(ctx, "invalid provider")
return routeutils.HandleAPIError(ctx, err)
}
if validationErrors := validation.ValidateVisit(&visit, &user); len(validationErrors) > 0 {
if validationErrors := validation.ValidateVisit(&visit, &authUser); len(validationErrors) > 0 {
return routeutils.ResponseAPICustomValidationError(ctx, "visit validation failed", validationErrors)
}
eligibility := viewmodel.Eligibility{}
eligibility.Provider.ProviderNPI = provider.InternalID
eligibility.Provider.ProviderName = provider.Name
eligibility.TrackingID = *visit.User.Member
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
@@ -78,7 +454,144 @@ func (c *controller) handle(ctx echo.Context) error {
return routeutils.ResponseAPIValidationError(ctx, err.Error())
}
return routeutils.ResponseAPIOK(ctx, resp)
user, err := c.svc.Users.GetByMemberID(*visit.User.Member)
if err != nil {
fmt.Println(err)
return routeutils.HandleAPIError(ctx, err)
}
if user.ID == "" {
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)
}
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)
}
if user.PhoneNumber != nil && len(*user.PhoneNumber) == 10 && !strings.Contains(*user.PhoneNumber, "+1") {
phoneNumber := fmt.Sprintf("+1%s", *user.PhoneNumber)
user.PhoneNumber = &phoneNumber
}
profile, err := c.svc.Profile.GetByKey("US")
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
user.Profiles = append(user.Profiles, profile)
user, err = c.svc.Users.Create(user, authUser)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
} else {
if visit.User.Email != nil && len(*visit.User.Email) > 0 {
user.Email = visit.User.Email
}
if visit.User.PhoneNumber != nil {
if len(*visit.User.PhoneNumber) == 10 && !strings.Contains(*visit.User.PhoneNumber, "+1") {
phoneNumber := fmt.Sprintf("+1%s", *visit.User.PhoneNumber)
visit.User.PhoneNumber = &phoneNumber
}
user.PhoneNumber = visit.User.PhoneNumber
}
err = c.svc.Users.UpdateLogin(user)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
}
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"
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,
}
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(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 to save address: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}
user.Addresses = append(user.Addresses, address)
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 {
return routeutils.HandleAPIError(ctx, err)
}
return routeutils.ResponseAPIOK(ctx, visit)
}
func (c *controller) handleGetByID(ctx echo.Context) error {
@@ -87,13 +600,14 @@ func (c *controller) handleGetByID(ctx echo.Context) error {
return routeutils.ResponseAPIValidationError(ctx, "visit_uuid param is mandatory")
}
user, err := auth.GetUserDetail(ctx, c.cfg)
authUser, err := auth.GetUserDetail(ctx, c.cfg)
if err != nil {
return routeutils.HandleAPIError(ctx, err)
}
resp, err := c.svc.Visits.GetByUUID(visit_uuid, user)
resp, err := c.svc.Visits.GetByUUID(visit_uuid, authUser)
if err != nil {
fmt.Println("Error to get Visit: ", err.Error())
return routeutils.HandleAPIError(ctx, err)
}

View File

@@ -2,6 +2,7 @@ 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"
)
@@ -9,13 +10,15 @@ 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) {
ctrl := controllerInstance(svc, cfg)
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)
r.GET(rootRoute, ctrl.handleGetAll)
r.GET(idRoute, ctrl.handleGetByID)