1

I have a flow and due to the complexity of the logic, I moved some of the logic into apex (However I need to use minimum apex).

I'm looping through some records and finding related records (I need only one to be added to the list). And if there are no records found, I'm adding the Id to a list of Strings (Later I need it to send an email from the flow).

But how can I pass the list of Strings back to the flow in addition to the list of records I'm returning? Is there a way to set flow variables from apex instead of returning?

    @InvocableMethod
    public static List<List<Maintenance__c>> getMaintenanceRecordsToBeCloned(List<List<Maintenance__c>> mains){

        List<Maintenance__c> maintenances = mains.get(0);
        List<Maintenance__c> listTobeCloned = new List<Maintenance__c>();
        List<String> missingRecords = new List<String>();

        Property_Agreement__c[] props = [SELECT Name, Id FROM Property_Agreement__c WHERE Active_c=True];

        //doing the following to get only one Maintenance record per Agreement
        for(Property_Agreement__c prop : props){
            Boolean isRecordFound = false;
            for(Maintenance__c main: maintenances){
                if(main.Property_Agreement__c == prop.Id){
                    listTobeCloned.add(main);
                    isRecordFound = true;
                    break;
                }
            }
            if(!isRecordFound){

                missingRecords.add(prop.Id);
            }
        }
        List<List<Maintenance__c>> result = new List<List<Maintenance__c>>();
        result.add(listTobeCloned);

        //is there a way to return missingRecords too?
        return result;
    }
1
  • I guess you need to create another flow and pass your value to that from your apex Mar 25, 2020 at 23:53

1 Answer 1

3

You use InvocableVariable annotations in a custom class. A demonstration of this is included in the documentation.

global class ConvertLeadAction {
  @InvocableMethod(label='Convert Leads')
  global static List<ConvertLeadActionResult> convertLeads(List<ConvertLeadActionRequest> requests) {
    List<ConvertLeadActionResult> results = new List<ConvertLeadActionResult>();
    for (ConvertLeadActionRequest request : requests) {
      results.add(convertLead(request));
    }
    return results;
  }

  public static ConvertLeadActionResult convertLead(ConvertLeadActionRequest request) {
    Database.LeadConvert lc = new Database.LeadConvert();
    lc.setLeadId(request.leadId);
    lc.setConvertedStatus(request.convertedStatus);

    if (request.accountId != null) {
        lc.setAccountId(request.accountId);
    }

    if (request.contactId != null) {
      lc.setContactId(request.contactId);
    }

    if (request.overWriteLeadSource != null && request.overWriteLeadSource) {
      lc.setOverwriteLeadSource(request.overWriteLeadSource);
    }

    if (request.createOpportunity != null && !request.createOpportunity) {
      lc.setDoNotCreateOpportunity(!request.createOpportunity);
    }

    if (request.opportunityName != null) {
      lc.setOpportunityName(request.opportunityName);
    }

    if (request.ownerId != null) {
      lc.setOwnerId(request.ownerId);
    }

    if (request.sendEmailToOwner != null && request.sendEmailToOwner) {
      lc.setSendNotificationEmail(request.sendEmailToOwner);
    }

    Database.LeadConvertResult lcr = Database.convertLead(lc, true);
    if (lcr.isSuccess()) {
      ConvertLeadActionResult result = new ConvertLeadActionResult();
      result.accountId = lcr.getAccountId();
      result.contactId = lcr.getContactId();
      result.opportunityId = lcr.getOpportunityId();
      return result;
    } else {
      throw new ConvertLeadActionException(lcr.getErrors()[0].getMessage());
    }
  }

  global class ConvertLeadActionRequest {
    @InvocableVariable(required=true)
    global ID leadId;

    @InvocableVariable(required=true)
    global String convertedStatus;

    @InvocableVariable
    global ID accountId;

    @InvocableVariable
    global ID contactId;

    @InvocableVariable
    global Boolean overWriteLeadSource;

    @InvocableVariable
    global Boolean createOpportunity;

    @InvocableVariable
    global String opportunityName;

    @InvocableVariable
    global ID ownerId;

    @InvocableVariable
    global Boolean sendEmailToOwner;
  }

  global class ConvertLeadActionResult {
    @InvocableVariable
    global ID accountId;

    @InvocableVariable
    global ID contactId;

    @InvocableVariable
    global ID opportunityId;
  }

  class ConvertLeadActionException extends Exception {}
}

Notice how you can set some to be required, or not, and you can choose multiple types; each can be input or output values, and will be exposed to the flow. Each corresponding index in the input should have a corresponding output in the return value.

In your example, it would look like:

@InvocableMethod
public static List<CloneMaintenanceResult> getMaintenanceRecordsToBeCloned(List<CloneMaintenanceRequest> mains){

...

public class CloneMaintenanceResult {
  @InvocableVariable Maintenance__c[] records;
  ...
}
public class CloneMaintenanceRequest {
  @InvocableVariable Maintenance__c[] records;
  ...
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .