initial commit 2

This commit is contained in:
Senad Uka
2018-04-25 13:16:36 +02:00
parent c1520d169c
commit 99c10b75fb
167 changed files with 25057 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
package bcbsi
import (
"sync"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
)
var (
instance *Service
once sync.Once
)
// Service holds the domain service repositories
type Service struct {
BXE *bxeService
}
// New returns a new domain Service instance
func New(cfg *config.Config) *Service {
once.Do(func() {
instance = &Service{
BXE: newBXEService(cfg),
}
})
return instance
}

View File

@@ -0,0 +1,150 @@
package bcbsimodel
import (
"encoding/xml"
"time"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
)
func GetEnvelope(eligibility viewmodel.Eligibility) Envelope {
soapEnvelope := Envelope{}
soapEnvelope.Namespace = "http://schemas.xmlsoap.org/soap/envelope/"
soapEnvelope.Body.MemberEligibilityRequest = GetEligibilityRequest(eligibility)
soapEnvelope.Body.MemberEligibilityRequest.Namespace = "http://v30.bx.services.bcbsa.com/eligibility-ext"
return soapEnvelope
}
func GetEligibilityRequest(eligibility viewmodel.Eligibility) MemberEligibilityRequest {
retVal := MemberEligibilityRequest{}
retVal.Version.MajorVersion = 3
retVal.Version.MinorVersion = 0
retVal.QueryHeader.TimeSent = time.Now().Format("2006-01-02T15:04:05")
retVal.QueryHeader.TrackingID = eligibility.TrackingID
retVal.Query.PayerInfo.PayerID = eligibility.Payer.PayerID
retVal.Query.PayerInfo.PayerName = eligibility.Payer.PayerName
retVal.Query.ProviderInfo.ProviderID = eligibility.Provider.ProviderID
retVal.Query.ProviderInfo.ProviderNPI = eligibility.Provider.ProviderNPI
retVal.Query.ProviderInfo.Provider.Organization = eligibility.Provider.ProviderName
retVal.Query.ProviderInfo.Provider.Name.First = eligibility.Provider.Name.First
retVal.Query.ProviderInfo.Provider.Name.Last = eligibility.Provider.Name.Last
retVal.Query.ProviderInfo.Provider.Name.Middle = eligibility.Provider.Name.Middle
retVal.Query.SubscriberInfo.SubscriberID = eligibility.Subscriber.SubscriberID
retVal.Query.SubscriberInfo.PatientType = eligibility.Subscriber.PatientType
retVal.Query.SubscriberInfo.Name.First = eligibility.Subscriber.Name.First
retVal.Query.SubscriberInfo.Name.Last = eligibility.Subscriber.Name.Last
retVal.Query.SubscriberInfo.Name.Middle = eligibility.Subscriber.Name.Middle
retVal.Query.SubscriberInfo.DemographicInfo.DateOfBirth = eligibility.Subscriber.DemographicInfo.DateOfBirth.Format("20060102")
retVal.Query.SubscriberInfo.DemographicInfo.GenderCode = eligibility.Subscriber.DemographicInfo.Gender
var dependents []Dependent
for _, d := range eligibility.Subscriber.Dependents {
dependent := Dependent{}
dependent.PatientAccountNumber = d.PatientAccountNumber
dependent.DemographicInfo.DateOfBirth = d.DemographicInfo.DateOfBirth.Format("20060102")
dependent.DemographicInfo.GenderCode = d.DemographicInfo.Gender
dependent.Name.First = d.Name.First
dependent.Name.Last = d.Name.Last
dependent.Name.Middle = d.Name.Middle
dependents = append(dependents, dependent)
}
if len(dependents) == 0 {
dependents = append(dependents, Dependent{})
}
retVal.Query.SubscriberInfo.DependentInfo.Dependents = dependents
retVal.Query.ServiceInfo.DateOfService = eligibility.ServiceInfo.DateOfService.Format("20060102")
retVal.Query.ServiceInfo.ServiceTypeCodes.ServiceTypeCode = eligibility.ServiceInfo.ServiceTypeCodes
return retVal
}
type Envelope struct {
XMLName xml.Name `xml:"soap:Envelope"`
Body EnvelopeBody `xml:"soap:Body"`
Namespace string `xml:"xmlns:soap,attr"`
}
type EnvelopeBody struct {
MemberEligibilityRequest MemberEligibilityRequest `xml:"elig:MemberEligibilityRequest"`
}
type MemberEligibilityRequest struct {
Version Version `xml:"version"`
QueryHeader QueryHeader `xml:"elig:eligibility-benefits-query-header"`
Query Query `xml:"elig:eligibility-benefits-query"`
Namespace string `xml:"xmlns:elig,attr"`
}
type Version struct {
MajorVersion int64 `xml:"majorVersion"`
MinorVersion int64 `xml:"minorVersion"`
}
type QueryHeader struct {
TrackingID string `xml:"tracking-id"`
TimeSent string `xml:"time-sent"`
}
type Query struct {
PayerInfo PayerInfo `xml:"elig:payer-info"`
ProviderInfo ProviderInfo `xml:"elig:provider-info"`
SubscriberInfo SubscriberInfo `xml:"elig:subscriber-info"`
ServiceInfo ServiceInfo `xml:"elig:service-info"`
}
type ServiceInfo struct {
DateOfService string `xml:"elig:date-of-service"`
ServiceTypeCodes ServiceTypeCodes `xml:"elig:service-type-codes"`
}
type ServiceTypeCodes struct {
ServiceTypeCode []string `xml:"elig:service-type-code"`
}
type SubscriberInfo struct {
PatientType string `xml:"elig:patient-type"`
SubscriberID string `xml:"elig:subscriber-id"`
Name Name `xml:"elig:name"`
DemographicInfo DemographicInfo `xml:"elig:demographic-info"`
DependentInfo DependentInfo `xml:"elig:dependent-info"`
}
type DependentInfo struct {
Dependents []Dependent `xml:"elig:dependent"`
}
type Dependent struct {
PatientAccountNumber string `xml:"elig:patient-account-number"`
Name Name `xml:"elig:name"`
DemographicInfo DemographicInfo `xml:"elig:demographic-info"`
}
type DemographicInfo struct {
DateOfBirth string `xml:"elig:date-of-birth"`
GenderCode string `xml:"elig:gender-code"`
}
type ProviderInfo struct {
ProviderID string `xml:"elig:provider-id"`
ProviderNPI string `xml:"elig:provider-npi"`
Provider Provider `xml:"elig:provider-name"`
}
type Provider struct {
Organization string `xml:"organization"`
Name Name `xml:"elig:name"`
}
type Name struct {
First string `xml:"elig:first"`
Last string `xml:"elig:last"`
Middle string `xml:"elig:middle"`
}
type PayerInfo struct {
PayerName string `xml:"elig:payer-name"`
PayerID string `xml:"elig:payer-id"`
}

View File

@@ -0,0 +1,44 @@
package bcbsimodel
import (
"encoding/xml"
)
type EnvelopeResponse struct {
XMLName xml.Name `xml:"Envelope"`
Body EnvelopeBodyResponse `xml:"Body"`
}
type EnvelopeBodyResponse struct {
MemberEligibilityResponse MemberEligibilityResponse `xml:"MemberEligibilityResponse"`
}
type MemberEligibilityResponse struct {
Version Version `xml:"version" json:"-"`
QueryResult QueryResult `xml:"eligibility-benefits-query-results" json:"results"`
}
type QueryResult struct {
HIPPA271 HIPAA271 `xml:"vcml-271" json:"raw"`
QueryResultSummary QueryResultSummary `xml:"query-result-summary" json:"summary"`
}
type HIPAA271 struct {
T271 string `xml:"t271" json:"t271"`
}
type QueryResultSummary struct {
BenefitsFound bool `xml:"benefits-found" json:"benefits_found"`
ProcessingInfo ProcessingInfo `xml:"processing-info" json:"-"`
}
type ProcessingInfo struct {
Message string `xml:"message" json:"-"`
}
type EntityResponse struct {
EntityID int64 `json:"entity_id"`
ID string `json:"id"`
Name string `json:"name"`
Status bool `json:"status"`
}

View File

@@ -0,0 +1,126 @@
package bcbsi
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/pquerna/ffjson/ffjson"
"bitbucket.org/nemt/nemt-portal-api/application/third/eligibility/bcbsi/bcbsimodel"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
)
type bxeService struct {
cfg *config.Config
}
func newBXEService(cfg *config.Config) *bxeService {
return &bxeService{
cfg: cfg,
}
}
func (s bxeService) getSignature(APIKey string, secretKey string) string {
rawKey := fmt.Sprintf("%s%s%v", APIKey, secretKey, time.Now().Unix())
hasher := md5.New()
hasher.Write([]byte(rawKey))
key := hex.EncodeToString(hasher.Sum(nil))
return strings.ToLower(key)
}
func (s bxeService) GetPayerDetails(subscriberID string) ([]bcbsimodel.EntityResponse, error) {
apiKey := s.cfg.Blue365.APIKey
secretKey := s.cfg.Blue365.Secret
URL := s.cfg.Blue365.URL
prefix := subscriberID[:3]
client := &http.Client{}
req, _ := http.NewRequest("GET", URL+"/"+prefix, bytes.NewBuffer([]byte{}))
req.Header.Add("X-Api-Key", apiKey)
req.Header.Add("X-Signature", s.getSignature(apiKey, secretKey))
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error Blue365: ", err)
return nil, err
}
defer resp.Body.Close()
bReturn, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error Blue365: ", err)
return nil, err
}
var response []bcbsimodel.EntityResponse
err = ffjson.Unmarshal(bReturn, &response)
if err != nil {
fmt.Println("Error Blue365: ", err)
return nil, err
}
return response, nil
}
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 = payer[0].ID
eligibility.Payer.PayerName = payer[0].Name
envelope := bcbsimodel.GetEnvelope(eligibility)
apiKey := s.cfg.BXE.APIKey
secretKey := s.cfg.BXE.Secret
bObj, err := xml.Marshal(envelope)
if err != nil {
return bcbsimodel.MemberEligibilityResponse{}, err
}
client := &http.Client{}
req, _ := http.NewRequest("POST", s.cfg.BXE.URL, bytes.NewBuffer(bObj))
req.Header.Add("Soapaction", "CheckEligibility")
req.Header.Add("Content-Type", "text/xml")
req.Header.Add("X-Api-Key", apiKey)
req.Header.Add("X-Signature", s.getSignature(apiKey, secretKey))
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error WebService: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
defer resp.Body.Close()
bReturn, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error WebService: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
sResponse := string(bReturn)
sResponse = strings.Replace(sResponse, "soapenv:Envelope", "Envelope", -1)
sResponse = strings.Replace(sResponse, "soapenv:Body", "Body", -1)
sResponse = strings.Replace(sResponse, "ns2:", "", -1)
var result bcbsimodel.EnvelopeResponse
err = xml.Unmarshal([]byte(sResponse), &result)
if err != nil {
fmt.Println("Error WebService: ", err)
return bcbsimodel.MemberEligibilityResponse{}, err
}
return result.Body.MemberEligibilityResponse, nil
}