Newer Version Available

This content describes an older version of this product. View Latest

AppointmentBookingInterop Interface

Contains default Apex implementation for healthcare appointment availability and booking.

Namespace

healthcloudext

Usage

Managing appointments from Health Cloud requires identifying the source system's time slot support; implementing the Health Cloud global AppointmentBookingInterop interface; transforming the input request to fit the source electronic health records (EHR) system; routing the request to the EHR system; and getting the appointment information back from an external appointment booking system.

The external appointment management system is commonly part of a larger electronic health records (EHR) system. The integration between Health Cloud and the EHR can be direct or via integration middleware such as Mulesoft.

The OrgPermissions.HealthCloud permission must be enabled in your Salesforce org to access the Health Cloud AppointmentBookingInterop interface and its methods.

You can use the default implementation AppointmentBookingInteropFhirAdapter provided by Health Cloud to make a call out to an external scheduling system of truth for appointment availability and booking. All communications with the external system use the FHIR 4 standard.

If implementing the default Health Cloud global interface is not right for your context, you can provide your own Apex class and integrate with your appointment management system in your own way. An ISV or a Salesfore partner having Health Cloud license can distribute customized Apex code to your organization using packages.

Use Salesforce platform Named Credentials to configure the class name and authentication for Apex callouts. Then, map the Name Credential name in the AppointmentBookingConfig setup object. The Apex delegator class uses the setup object to invoke the corresponding implementation between the default implementation or your own provided Apex implementation. See Named Credentials as Callout Endpoints in the Apex Developer Guide.

AppointmentBookingInterop Methods

The following are methods for AppointmentBookingInterop.

bookAppointment(var1)

Creates the healthcare appointment in the external scheduling system.

Signature

public healthcloudext.BookAppointmentResponse bookAppointment(healthcloudext.BookAppointmentRequest var1)

cancelAppointment(var1)

Cancels the booking appointment in the external scheduling system.

Signature

public healthcloudext.CancelAppointmentResponse cancelAppointment(healthcloudext.CancelAppointmentRequest var1)

findSlots(var1)

Finds the available time slots for providers who match the patient’s needs.

Signature

public Map<String,List<healthcloudext.Slot>> findSlots(healthcloudext.FindSlotsRequest var1)

Parameters

var1
Type: healthcloudext.FindSlotsRequest

Return Value

Type: Map<String,List<healthcloudext.Slot>>

getSlotStatus(var1)

Retrieves the status of the time period slot that’s assigned to the appointment.

Signature

public healthcloudext.Slot getSlotStatus(healthcloudext.GetSlotStatusRequest var1)

Parameters

var1
Type: healthcloudext.GetSlotStatusRequest

Return Value

Type: healthcloudext.Slot

AppointmentBookingInterop Example Implementation

This is an example implementation of the default class AppointmentBookingInteropFhirAdapter that implements the healthcloudext.AppointmentBookingInterop interface.

1global class AppointmentBookingInteropFhirAdapter implements AppointmentBookingInterop{
2   static final String DEFAULT_ERROR_MESSAGE = 'Error during callout to the external system';
3   static final String DEFAULT_ERROR_CODE = '500';
4
5   /*
6      @Method Name: findSlots
7      @Param: request Type: FindSlotsRequest
8      @Desc: FindSlot implementation
9   */
10   global Map<String,List<Slot>> findSlots(FindSlotsRequest request){
11      Map<String,List<Slot>> response = new Map<String,List<Slot>>();
12      try {
13        HttpRequest httpReq = FindSlotsMapper.mapHttpRequest(request);
14        Http http = new Http();
15        HTTPResponse res = http.send(httpReq);
16        System.debug('Response Body >>>>'+res.getBody());
17        Integer statusCode = res.getStatusCode();
18        if(statusCode == 200) {
19           FHIR.Bundle bundle = FHIRParser.parseSlotBundle(res.getBody());
20           return FindSlotsMapper.mapResponse(request,bundle);
21        } else {
22           processErrorResponse(res);
23        }
24      } catch(AppointmentManagementException e) {
25        throw e;
26      } catch(Exception e){
27        throw new AppointmentManagementException(e.getMessage(), DEFAULT_ERROR_CODE, '', e);
28      }
29      return response;
30   }
31   public void processErrorResponse(HTTPResponse res){
32      try {
33        FHIR.OperationOutcome outcome = FHIRParser.parseOperationOutcome(res.getBody());
34        throw new AppointmentManagementException(getErrorMessage(outcome), String.valueOf(res.getStatusCode()), res.getBody());
35      }catch(Exception e){//If couldn't able to parse to OperationOutcome, issue might be from Middleware
36        if(res.getStatusCode() == 404) {
37           throw new AppointmentManagementException('Find available slots endpoint not found, check the Appointment Booking Config & Appointment Booking URL Config', String.valueOf(res.getStatusCode()), res.getBody());
38        }else {
39           throw new AppointmentManagementException(e.getMessage(), DEFAULT_ERROR_CODE, '');
40        }
41      }
42   }
43   /*
44      @Method Name: bookAppointment
45      @Param: request Type: BookAppointmentRequest
46      @Desc: Book Appointment implementation
47   */
48   global BookAppointmentResponse bookAppointment(BookAppointmentRequest request){
49   BookAppointmentResponse response;
50      try{
51        HttpRequest httpReq = BookAppointmentMapper.mapHttpRequest(request);
52        Http http = new Http();
53        HTTPResponse res = http.send(httpReq);
54        System.debug('Response Body >>>>'+res.getBody());
55        Integer statusCode = res.getStatusCode();
56        if(statusCode == 200 || statusCode == 201) {
57           FHIR.Appointment appointment = FHIRParser.parseAppointment(res.getBody());
58           response = BookAppointmentMapper.mapResponse(request, appointment, res.getBody());
59        } else {
60           FHIR.OperationOutcome outcome = FHIRParser.parseOperationOutcome(res.getBody());
61           throw new AppointmentManagementException(getErrorMessage(outcome), String.valueOf(statusCode), res.getBody());
62        }
63      }catch (Exception e){
64        throw new AppointmentManagementException(DEFAULT_ERROR_MESSAGE, DEFAULT_ERROR_CODE, '');
65      }
66      return response;
67   }
68
69   /*
70   @Method Name: getSlotStatus
71   @Param: request Type: GetSlotStatusRequest
72   @Desc: getSlotStatus implementation
73   */
74   global Slot getSlotStatus(GetSlotStatusRequest request){
75      try{
76        HttpRequest httpReq = GetSlotStatusMapper.mapHttpRequest(request);
77        Http http = new Http();
78        HTTPResponse res = http.send(httpReq);
79        if(res.getStatusCode() == 200) {
80           FHIR.Slot slot = FHIRParser.parseSlot(res.getBody());
81           return GetSlotStatusMapper.mapResponse(slot);
82        }
83        else {
84           FHIR.OperationOutcome outcome = FHIRParser.parseOperationOutcome(res.getBody());
85           throw new AppointmentManagementException(getErrorMessage(outcome), String.valueOf(res.getStatusCode()), res.getBody());
86        }
87      }catch (Exception e){
88        throw new AppointmentManagementException(DEFAULT_ERROR_MESSAGE, DEFAULT_ERROR_CODE, '');
89      }
90   }
91
92   /*
93   @Method Name: cancelAppointment
94   @Param: request Type: CancelAppointmentRequest
95   @Desc: Cancel Appointment implementation
96   */
97   global CancelAppointmentResponse cancelAppointment(CancelAppointmentRequest request){
98      try{
99        HttpRequest httpReq = CancelAppointmentMapper.mapHttpRequest(request);
100        Http http = new Http();
101        HTTPResponse res = http.send(httpReq);
102        System.debug('Response Body >>>>'+res.getBody());
103        Integer statusCode = res.getStatusCode();
104        CancelAppointmentResponse response;
105        if(statusCode == 200 || statusCode == 201) {
106           FHIR.Appointment appointment = FHIRParser.parseAppointment(res.getBody());
107           response = CancelAppointmentMapper.mapResponse( appointment, res.getBody());
108        } else {
109           FHIR.OperationOutcome outcome = FHIRParser.parseOperationOutcome(res.getBody());
110           throw new AppointmentManagementException(getErrorMessage(outcome), String.valueOf(statusCode), res.getBody());
111        }
112      return response;
113      }catch (Exception e){
114        throw new AppointmentManagementException(DEFAULT_ERROR_MESSAGE, DEFAULT_ERROR_CODE, '');
115      }
116   }
117
118   public static String getErrorMessage(FHIR.OperationOutcome outcome){
119      String errorMessage = DEFAULT_ERROR_MESSAGE;
120      if(outcome != null) {
121        if(outcome.issue != null && outcome.issue.size() > 0) {
122           if(outcome.issue[0].details != null && outcome.issue[0].details.text != null) {
123              errorMessage = outcome.issue[0].details.text;
124           } else if(outcome.issue[0].diagnostics != null) {
125              errorMessage = outcome.issue[0].diagnostics;
126           }
127        }
128      }
129      return errorMessage;
130   }
131}