Newer Version Available

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

Create a Custom Apex Class for the Patient Creation Job Flow

Create a custom Apex class that extends a base class and implements an interface from the Health Cloud package. The custom class overrides the methods in the base class and the interface.

As the Candidate Patient custom object is being retired, use the Lead object instead of the Candidate Patient object. If you need a Candidate Patient field that Lead doesn't support, create the fields.

Note

Your Apex class extends the HealthCloudGA.MoiJobFlowFactory.MoiJobBase base class and implements the HealthCloudGA.MoiJobFlowFactory.MoiIJob interface from the Health Cloud package. Your class signature looks as follows:
1public with sharing class InvokePatientDataMigrate 
2    extends HealthCloudGA.MoiJobFlowFactory.MoiJobBase 
3    implements HealthCloudGA.MoiJobFlowFactory.MoiIJob { }
Your class overrides two methods that are in the base class.
boolean processJob(HealthCloudGA.MoiJobFlowFactory.MoiIJobContext flowCtxts)
Override this method to implement the logic of your data migration job that is part of the patient creation flow. In this method, you call another method to make a callout to the external EHR system to get more medical records for the patient.
The patient creation job flow runs all the jobs as a single Apex transaction. Partial data changes aren’t saved when an error occurs because all changes are rolled back in that transaction. Any callouts must be invoked from a future method so that the data from the first two jobs is saved even if the callout fails. Future methods are executed asynchronously, in the background. For example, this method signature represents the callout utility method in our sample.
1@Future(callout=true)
2private static void invokeIntegration(String jsonPatientIds)
The type of the parameter passed to the processJob() method is the HealthCloudGA.MoiJobFlowFactory.MoiIJobContext class, installed from the Health Cloud package. The patient creation job flow uses this context object to pass information about the created objects to the next job. The jobs for creating a patient populate this context object with the account and contact. Next, the job for creating the care plan accesses the objects in the context to link the case (care plan record type) to CaseTeam members. You can use the objects in the context parameter to discover which objects have been created in Health Cloud and link them to the EHR system. The objects you can access from the flowCtxts parameter are:
  • Account
  • Contact
  • CandidatePatient__c
  • Case (CarePlan record type)
You can obtain these objects by calling getContextData() on the flowCtxts parameter. The getContextData() method returns a list of maps. Each map corresponds to the context of one patient and contains the objects related to that patient. The map is keyed by the name of the object. For example, this snippet shows how to get the CandidatePatient__c object from a returned map object:
1for (Map<String, Object> flowCtxt : flowCtxts.getContextData()) {
2    HealthCloudGA__CandidatePatient__c candidatePatient = 
3        (HealthCloudGA__CandidatePatient__c)flowCtxt.get('CandidatePatient__c'); }
HealthCloudGA.MoiJobFlowFactory.MoiIErrorHandler getErrorHandler()
Override this method to add error handling logic when an exception is thrown from processJob(). This method returns an instance of a class that performs error handling. The class performing the error handling must implement the HealthCloudGA.MoiJobFlowFactory.MoiIErrorHandler interface and override its method:
1public void handleError(HealthCloudGA.MoiJobFlowFactory.MoiIJobContext context, Exception e)

We’ve provided a sample Apex class that you can copy and modify to suit your needs. The implementation of the callout in the invokeIntegration helper method is not provided and is left for you to provide. Details of how to communicate with the service endpoint and fetch data differs based on what you want to accomplish. For information about how to make callouts from Apex, see Invoking Callouts Using Apex in the Lightning Platform Apex Code Developer's Guide.

You can create an Apex class by using various tools. This walkthrough uses the Developer Console.

  1. Register the service endpoint as a remote site in Salesforce.
    This has to be done before the callout in this integration can be made. See Configure Remote Site Settings for instructions.
  2. From Setup, click Your Name and then click Developer Console to open the Developer Console.
  3. Click File | New | Apex Class.
  4. Enter InvokePatientDataMigrate for the class name, and then press OK.
  5. Delete the auto-generated content and paste the following sample.
    1public with sharing class InvokePatientDataMigrate extends HealthCloudGA.MoiJobFlowFactory.MoiJobBase 
    2        implements HealthCloudGA.MoiJobFlowFactory.MoiIJob {
    3
    4    private static final String CTXTVAR_ACCOUNT = 'Account';
    5    private static final String CTXTVAR_CONTACT = 'Contact';
    6    private static final String CTXTVAR_CAREPLAN = 'CarePlan';  
    7    private static final String CTXTVAR_CANDIDIATEPATIENT = 'CandidatePatient__c';
    8    
    9    public with sharing class IntegrationErrorHandler implements 
    10            HealthCloudGA.MoiJobFlowFactory.MoiIErrorHandler {
    11        public void handleError(HealthCloudGA.MoiJobFlowFactory.MoiIJobContext context, 
    12                                Exception e) {
    13           // Code can be placed here to address the failure 
    14           System.debug('Exception: '+e+' thrown on Job with context '+context); 
    15           //No Exception
    16        }
    17    }       
    18        
    19    public override HealthCloudGA.MoiJobFlowFactory.MoiIErrorHandler getErrorHandler() {
    20        return (HealthCloudGA.MoiJobFlowFactory.MoiIErrorHandler) 
    21                new IntegrationErrorHandler();
    22    }
    23
    24    // Invokes asynchronous migration of patient data for list of patient identifiers
    25    @Future(callout=true)
    26    private static void invokeIntegration(String jsonPatientIds){
    27
    28        String SalesforceOrgId = System.UserInfo.getOrganizationId();
    29
    30        ////////////////////////////////////////////////////////////////////
    31        // Make call to integration system passing patient Identifiers
    32        // and organization Id.
    33        // Integration System should respond asynchronously by push Patient 
    34        // EHR records to the org.
    35        ////////////////////////////////////////////////////////////////////
    36    }
    37      
    38    private class PatientId{
    39          public PatientId(String MedicalRecordNumber, Id accountId, Id contactId, 
    40                           Id carePlanId){
    41              this.SFDCMedicalRecordNumber = MedicalRecordNumber;
    42              this.SFDCAccountId = accountId;
    43              this.SFDCContactId = contactId;
    44              this.carePlanId = carePlanId;
    45              
    46          }
    47          // Id of account created in CreateIndividual Job          
    48          public Id SFDCAccountId;
    49          // Id of contact created in CreateIndividual Job
    50          public Id SFDCContactId;
    51          // Id of Careplan created in CreateCarePlan job
    52          public Id carePlanId;
    53          // Medical Record Number of patient in external Electronic 
    54          // Health Record System
    55          public String SFDCMedicalRecordNumber;
    56          
    57    }
    58
    59
    60    // Override processJob method to be called when this job is invoked 
    61    // by MoiJobFlowManager.
    62    public override boolean processJob(HealthCloudGA.MoiJobFlowFactory.MoiIJobContext 
    63                                       flowCtxts) {
    64        
    65        System.debug('Entered InvokeIntegration.processJob');
    66        // Compile List of strings with Patient Ids 
    67        // {CandidatePatient__c.MedicalRecordNumber_c, Account.Id and Contact.Id}
    68        // to pass to integration system to invoke asynchronous publish 
    69        // of patient EHR records.     
    70        List<PatientId> patientIds = new List<PatientId>();
    71        
    72        for (Map<String, Object> flowCtxt : flowCtxts.getContextData()) {
    73            HealthCloudGA__CandidatePatient__c candidatePatient = 
    74                (HealthCloudGA__CandidatePatient__c)flowCtxt.get(
    75                        CTXTVAR_CANDIDIATEPATIENT);
    76            if (candidatePatient == null || 
    77                candidatePatient.HealthCloudGA__MedicalRecordNumber__c == '')
    78                throw new IntegrationException(
    79                    'Failure: No CandidatePatient record set. ' + candidatePatient);
    80            
    81            patientIds.add(
    82                new PatientId(candidatePatient.HealthCloudGA__MedicalRecordNumber__c,
    83                              ((Account)flowCtxt.get(CTXTVAR_ACCOUNT)).Id,
    84                              ((Contact)flowCtxt.get(CTXTVAR_CONTACT)).Id,
    85                              ((Case)flowCtxt.get(CTXTVAR_CAREPLAN)).Id)
    86                          );                             
    87        }/* for Flow Ctxts (on for each patient in creation flow */
    88
    89        System.debug('Calling future method InvokeIntegration('+patientIds+')');
    90        invokeIntegration(JSON.serializePretty(patientIds));
    91        return true;
    92    } // processJob()
    93        
    94    class IntegrationException extends Exception{}
    95} //class InvokePatientDataMigrate
  6. Click File | Save.