13

@InvocableMethod annotation is not allowing to pass two parameters. I want to invoke a method through process builder which is having :

  • Input type : Date, Date
  • Output type : Integer

Is there any way to achieve this requirement?

1
  • 1
    Kindly share what have you tried so far, to get proper help
    – Raul
    Jan 18, 2017 at 12:31

4 Answers 4

12

You can do this by using an inner class within the same class you have the InvocableMethod. And receive a List of said class in your Invocable Method.

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 {}
}

Original Source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableVariable.htm

If you have any doubts on how to implement this feel free to comment/ask.

7
  1. You cannot use the return value of the @InvocableMethod in Process builder. The return values of these methods can be used only in flows or when invoked through REST API. Check this answer for more details: accessing the return value of an InvocableMethod in process builder
  2. Regarding how to pass two parameters, Override your actual method with another method which takes one parameter of List of primitives then split and call your actual method. Something like this:

    public with sharing class ExampleClass {
    
        public static Integer innerMethod(Date d1,Date d2){
            return d1.monthsBetween(d2);
        }
    
        @InvocableMethod(label='Example' description='Example')
        public static void innerMethodInvocable(List<Date> dates){
            innerMethod(dates[0],dates[1]);
        }    
    }
    
3

Taken from the development guide

There can be at most one input parameter and its data type must be one of the following:

  • A list of a primitive data type or a list of lists of a primitive data type – the generic Object type is not supported.
  • A list of an sObject type or a list of lists of an sObject type – the generic sObject type is not supported.
  • A list of a user-defined type, containing variables of the supported types and with the InvocableVariable annotation. Create a custom global or public Apex class to implement your data type, and make sure your class contains at least one member variable with the invocable variable annotation.

I suggest you just query what you need from inside the Invocable Method.

0

You can see the example below how to pass more variable. It is recommended to use an inner class as input parameter. It is scalable, anytime you can add new variables (with required/optional) options for any data type.

@InvocableVariable

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableVariable.htm

1
  • 1
    If this link answers the question, please cite some of its relevant content so that this answer on its own will actually stand as an answer to the question.
    – Adrian Larson
    Jan 21, 2018 at 13:35

You must log in to answer this question.

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