Skip to content

Commit

Permalink
feat: add get facilities method for retrieving facilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Salaton committed Oct 26, 2023
1 parent 94a75e7 commit 8e84601
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 46 deletions.
17 changes: 1 addition & 16 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,7 @@ func (cl *client) MakeRequest(ctx context.Context, method, path string, queryPar
}
request = req

case http.MethodPost:
encoded, err := json.Marshal(body)
if err != nil {
return nil, err
}

payload := bytes.NewBuffer(encoded)

req, err := http.NewRequestWithContext(ctx, method, urlPath, payload)
if err != nil {
return nil, err
}

request = req

case http.MethodPatch:
case http.MethodPost, http.MethodPatch:
encoded, err := json.Marshal(body)
if err != nil {
return nil, err
Expand Down
99 changes: 72 additions & 27 deletions healthcrm.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ var (
BaseURL = serverutils.MustGetEnvVar("HEALTH_CRM_BASE_URL")
)

const (
facilitiesPath = "/v1/facilities/facilities/"
// TODO: use an environment variable
crmServiceCode = "05"
)

// HealthCRMLib interacts with the healthcrm APIs
type HealthCRMLib struct {
client *client
Expand Down Expand Up @@ -60,33 +66,6 @@ func (h *HealthCRMLib) CreateFacility(ctx context.Context, facility *Facility) (
return facilityResponse, nil
}

// GetFacilities is used to fetch facilities from health crm facility registry
func (h *HealthCRMLib) GetFacilities(ctx context.Context) (*FacilityPage, error) {
path := "/v1/facilities/facilities/"
response, err := h.client.MakeRequest(ctx, http.MethodGet, path, nil, nil)
if err != nil {
return nil, err
}

respBytes, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("could not read response: %w", err)
}

if response.StatusCode != http.StatusOK {
return nil, errors.New(string(respBytes))
}

var facilityPage *FacilityPage

err = json.Unmarshal(respBytes, &facilityPage)
if err != nil {
return nil, err
}

return facilityPage, nil
}

// GetFacilityByID is used to fetch facilities from health crm facility registry using its ID
func (h *HealthCRMLib) GetFacilityByID(ctx context.Context, id string) (*FacilityOutput, error) {
path := fmt.Sprintf("/v1/facilities/facilities/%s/", id)
Expand Down Expand Up @@ -272,3 +251,69 @@ func (h *HealthCRMLib) LinkServiceToFacility(ctx context.Context, facilityID str

return output, nil
}

// GetFacilities retrieves a list of facilities associated with MyCareHub
// stored in HealthCRM. The method allows for filtering facilities by location proximity and services offered.
//
// Parameters:
// - location: A Location struct that represents the reference location.
// If provided, facilities will be filtered based on proximity
// to this location.
// - pagination: A Pagination struct containing options for paginating
// the results.
// - serviceIDs: A parameter that allows specifying one or more
// service IDs. Facilities offering these services will be
// included in the results. You can pass multiple service
// IDs as separate arguments (e.g., GetFacilities(ctx, location, pagination, []string{"1234", "178"})).
//
// Usage:
// Example 1: Retrieve facilities by location and service IDs:
// --> E.g If we are searching with service ID that represents Chemotherapy, the response
// will be a list of facilities that offer Chemotherapy and it will be ordered with proximity
//
// Example 2: Retrieve facilities by location without specifying services:
// This will return a list of all facilities ordered by the proximity
//
// Example 3: Retrieve all facilities without specifying location or services:
func (h *HealthCRMLib) GetFacilities(ctx context.Context, location *Coordinates, serviceIDs []string, pagination *Pagination) (*FacilityPage, error) {
queryParams := make(map[string]string)

if pagination != nil {
queryParams["page_size"] = pagination.PageSize
queryParams["page"] = pagination.Page
}

if location != nil {
queryParams["ref_location"] = location.ToString()
}

for _, id := range serviceIDs {
queryParams["service"] = id
}

queryParams["crm_service_code"] = crmServiceCode

response, err := h.client.MakeRequest(ctx, http.MethodGet, facilitiesPath, queryParams, nil)
if err != nil {
return nil, err
}

respBytes, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("could not read response: %w", err)
}

if response.StatusCode != http.StatusOK {
// TODO: Get the exact error message (should be formatted well)
return nil, errors.New(string(respBytes))
}

var facilityPage *FacilityPage

err = json.Unmarshal(respBytes, &facilityPage)
if err != nil {
return nil, err
}

return facilityPage, nil
}
12 changes: 10 additions & 2 deletions healthcrm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ func TestHealthCRMLib_CreateFacility(t *testing.T) {

func TestHealthCRMLib_GetFacilities(t *testing.T) {
type args struct {
ctx context.Context
ctx context.Context
location *Coordinates
serviceIDs []string
pagination *Pagination
}
tests := []struct {
name string
Expand All @@ -187,6 +190,11 @@ func TestHealthCRMLib_GetFacilities(t *testing.T) {
name: "Happy case: fetch facility(ies)",
args: args{
ctx: context.Background(),
location: &Coordinates{
Latitude: "-1.29",
Longitude: "36.79",
},
serviceIDs: []string{"1234"},
},
wantErr: false,
},
Expand Down Expand Up @@ -266,7 +274,7 @@ func TestHealthCRMLib_GetFacilities(t *testing.T) {
t.Errorf("unable to initialize sdk: %v", err)
}

_, err = h.GetFacilities(tt.args.ctx)
_, err = h.GetFacilities(tt.args.ctx, tt.args.location, tt.args.serviceIDs, tt.args.pagination)
if (err != nil) != tt.wantErr {
t.Errorf("HealthCRMLib.GetFacilities() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
15 changes: 14 additions & 1 deletion input.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package healthcrm

import "fmt"

// Facility is the hospitals data class
type Facility struct {
ID string `json:"id,omitempty"`
Expand All @@ -15,12 +17,23 @@ type Facility struct {
BusinessHours []BusinessHours `json:"businesshours,omitempty"`
}

// Coordinates models the geographical's location data class of a facility
// Coordinates represents geographical coordinates using latitude and longitude.
// Latitude measures the north-south position, while longitude measures
// the east-west position.
type Coordinates struct {
Latitude string `json:"latitude,omitempty"`
Longitude string `json:"longitude,omitempty"`
}

// ToString returns the location in comma-separated values format.
// The order of values in the string is longitude,latitude.
// The latitude and longitude are formatted up to 5 decimal places.
// For example, if the Location has Latitude 36.79 and Longitude -1.29,
// the returned string will be "-1.29, 36.79".
func (c Coordinates) ToString() string {
return fmt.Sprintf("%v, %v", c.Longitude, c.Latitude)
}

// Contacts models facility's model data class
type Contacts struct {
ContactType string `json:"contact_type,omitempty"`
Expand Down

0 comments on commit 8e84601

Please sign in to comment.