Newer Version Available

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

Sample Process.Plugin Implementation for Lead Conversion

In this example, an Apex class implements the Process.Plugin interface and converts a lead into an account, contact, and optionally, an opportunity. Test methods for the plug-in are also included. This implementation can be called from a flow via a legacy Apex action.

We recommend using the @InvocableMethod annotation instead of the Process.Plugin interface.

  • The interface doesn’t support Blob, Collection, and sObject, data types, and it doesn’t support bulk operations. After you implement the interface on a class, the class can be referenced only from flows.
  • The annotation supports all data types and bulk operations. After you implement the annotation on a class, the class can be referenced from flows, processes, and the Custom Invocable Actions REST API endpoint.
  • Legacy Apex actions aren’t supported in auto-layout in Flow Builder. Legacy Apex actions are only available to be added in free-form in Flow Builder. Existing actions can be edited in both auto-layout and free-form mode.

Tip

1// Converts a lead as an action in a flow.
2global class VWFConvertLead implements Process.Plugin {
3    // This method runs when called by a flow's legacy Apex action.
4    global Process.PluginResult invoke(
5        Process.PluginRequest request) {
6            
7        // Set up variables to store input parameters from 
8        // the flow.
9        String leadID = (String) request.inputParameters.get(
10            'LeadID');
11        String contactID = (String) 
12            request.inputParameters.get('ContactID');
13        String accountID = (String) 
14            request.inputParameters.get('AccountID');
15        String convertedStatus = (String) 
16            request.inputParameters.get('ConvertedStatus');
17        Boolean overWriteLeadSource = (Boolean) 
18            request.inputParameters.get('OverwriteLeadSource');
19        Boolean createOpportunity = (Boolean) 
20            request.inputParameters.get('CreateOpportunity');
21        String opportunityName = (String) 
22            request.inputParameters.get('ContactID');
23        Boolean sendEmailToOwner = (Boolean) 
24            request.inputParameters.get('SendEmailToOwner');   
25        
26        // Set the default handling for booleans. 
27        if (overWriteLeadSource == null) 
28            overWriteLeadSource = false;
29        if (createOpportunity == null) 
30            createOpportunity = true;
31        if (sendEmailToOwner == null) 
32            sendEmailToOwner = false;
33        
34        // Convert the lead by passing it to a helper method.
35        Map<String,Object> result = new Map<String,Object>();
36        result = convertLead(leadID, contactID, accountID, 
37            convertedStatus, overWriteLeadSource, 
38            createOpportunity, opportunityName, 
39            sendEmailToOwner);
40 
41        return new Process.PluginResult(result); 
42    }
43    
44    // This method describes the plug-in and its inputs from
45    // and outputs to the flow.
46    // Implementing this method makes the class available 
47    // in Flow Builder as a legacy Apex action.
48    global Process.PluginDescribeResult describe() {
49        // Set up plugin metadata
50        Process.PluginDescribeResult result = new 
51            Process.PluginDescribeResult();
52        result.description = 
53            'The LeadConvert Flow Plug-in converts a lead into ' + 
54            'an account, a contact, and ' + 
55            '(optionally)an opportunity.';
56        result.tag = 'Lead Management';
57        
58        // Create a list that stores both mandatory and optional 
59        // input parameters from the flow.
60        // NOTE: Only primitive types (STRING, NUMBER, etc.) are 
61        // supported. Collections aren't supported.
62        result.inputParameters = new 
63            List<Process.PluginDescribeResult.InputParameter>{
64            // Lead ID (mandatory)
65            new Process.PluginDescribeResult.InputParameter(
66                'LeadID', 
67                Process.PluginDescribeResult.ParameterType.STRING, 
68                true),
69            // Account Id (optional)
70            new Process.PluginDescribeResult.InputParameter(
71                'AccountID', 
72                Process.PluginDescribeResult.ParameterType.STRING, 
73                false),
74            // Contact ID (optional)
75            new Process.PluginDescribeResult.InputParameter(
76                'ContactID', 
77                Process.PluginDescribeResult.ParameterType.STRING, 
78                false),            
79            // Status to use once converted
80            new Process.PluginDescribeResult.InputParameter(
81                'ConvertedStatus', 
82                Process.PluginDescribeResult.ParameterType.STRING, 
83                true),
84            new Process.PluginDescribeResult.InputParameter(
85                'OpportunityName', 
86                Process.PluginDescribeResult.ParameterType.STRING, 
87                false),
88            new Process.PluginDescribeResult.InputParameter(
89                'OverwriteLeadSource', 
90                Process.PluginDescribeResult.ParameterType.BOOLEAN, 
91                false),
92            new Process.PluginDescribeResult.InputParameter(
93                'CreateOpportunity', 
94                Process.PluginDescribeResult.ParameterType.BOOLEAN, 
95                false),
96            new Process.PluginDescribeResult.InputParameter(
97                'SendEmailToOwner', 
98                Process.PluginDescribeResult.ParameterType.BOOLEAN, 
99                false)                                                   
100        };
101
102        // Create a list that stores output parameters sent 
103        // to the flow.
104        result.outputParameters = new List<
105            Process.PluginDescribeResult.OutputParameter>{
106            // Account ID of the converted lead
107            new Process.PluginDescribeResult.OutputParameter(
108                'AccountID', 
109                Process.PluginDescribeResult.ParameterType.STRING),
110            // Contact ID of the converted lead
111            new Process.PluginDescribeResult.OutputParameter(
112                'ContactID', 
113                Process.PluginDescribeResult.ParameterType.STRING),
114            // Opportunity ID of the converted lead
115            new Process.PluginDescribeResult.OutputParameter(
116                'OpportunityID', 
117                Process.PluginDescribeResult.ParameterType.STRING)                
118        };
119
120        return result;
121    }
122        
123    /**
124     * Implementation of the LeadConvert plug-in.
125     * Converts a given lead with several options:
126     * leadID - ID of the lead to convert
127     * contactID - 
128     * accountID - ID of the Account to attach the converted 
129     *  Lead/Contact/Opportunity to.
130     * convertedStatus - 
131     * overWriteLeadSource - 
132     * createOpportunity - true if you want to create a new 
133     *  Opportunity upon conversion
134     * opportunityName - Name of the new Opportunity.
135     * sendEmailtoOwner - true if you are changing owners upon 
136     *  conversion and want to notify the new Opportunity owner.
137     *
138     * returns: a Map with the following output:
139     * AccountID - ID of the Account created or attached 
140     *  to upon conversion.
141     * ContactID - ID of the Contact created or attached 
142     *  to upon conversion.
143     * OpportunityID - ID of the Opportunity created 
144     *  upon conversion.
145     */
146    public Map<String,String> convertLead (
147                               String leadID,
148                               String contactID,
149                               String accountID,
150                               String convertedStatus,
151                               Boolean overWriteLeadSource,
152                               Boolean createOpportunity,
153                               String opportunityName,
154                               Boolean sendEmailToOwner
155        ) {
156        Map<String,String> result = new Map<String,String>();
157                                
158        if (leadId == null) throw new ConvertLeadPluginException(
159            'Lead Id cannot be null');
160        
161        // check for multiple leads with the same ID
162        Lead[] leads = [Select Id, FirstName, LastName, Company 
163            From Lead where Id = :leadID];
164        if (leads.size() > 0) {
165            Lead l = leads[0];
166            // CheckAccount = true, checkContact = false
167            if (accountID == null && l.Company != null) {
168                Account[] accounts = [Select Id, Name FROM Account 
169                    where Name = :l.Company LIMIT 1];
170                if (accounts.size() > 0) {
171                    accountId = accounts[0].id;
172                }
173            }
174            
175            // Perform the lead conversion.
176            Database.LeadConvert lc = new Database.LeadConvert();
177            lc.setLeadId(leadID);
178            lc.setOverwriteLeadSource(overWriteLeadSource);
179            lc.setDoNotCreateOpportunity(!createOpportunity);
180            lc.setConvertedStatus(convertedStatus);
181            if (sendEmailToOwner != null) lc.setSendNotificationEmail(
182                sendEmailToOwner);
183            if (accountId != null && accountId.length() > 0) 
184                lc.setAccountId(accountId);
185            if (contactId != null && contactId.length() > 0) 
186                lc.setContactId(contactId);
187            if (createOpportunity) {
188                lc.setOpportunityName(opportunityName);
189            }
190            
191            Database.LeadConvertResult lcr = Database.convertLead(
192                lc, true);
193            if (lcr.isSuccess()) {
194                result.put('AccountID', lcr.getAccountId());
195                result.put('ContactID', lcr.getContactId());
196                if (createOpportunity) {
197                    result.put('OpportunityID', 
198                        lcr.getOpportunityId());
199                }
200            } else {
201                String error = lcr.getErrors()[0].getMessage();
202                throw new ConvertLeadPluginException(error);
203            }
204        } else { 
205            throw new ConvertLeadPluginException(
206                'No leads found with Id : "' + leadId + '"');
207        }
208        return result;
209    }
210        
211    // Utility exception class
212    class ConvertLeadPluginException extends Exception {}
213}
1// Test class for the lead convert Apex plug-in.
2@isTest
3private class VWFConvertLeadTest {
4    static testMethod void basicTest() {
5        // Create test lead
6        Lead testLead = new Lead(
7           Company='Test Lead',FirstName='John',LastName='Doe');
8        insert testLead;
9    
10        LeadStatus convertStatus = 
11           [Select Id, MasterLabel from LeadStatus 
12           where IsConverted=true limit 1]; 
13        
14        // Create test conversion
15        VWFConvertLead aLeadPlugin = new VWFConvertLead();
16        Map<String,Object> inputParams = new Map<String,Object>();
17        Map<String,Object> outputParams = new Map<String,Object>();
18
19        inputParams.put('LeadID',testLead.ID);
20        inputParams.put('ConvertedStatus', 
21           convertStatus.MasterLabel);
22
23        Process.PluginRequest request = new 
24           Process.PluginRequest(inputParams);
25        Process.PluginResult result;
26        result = aLeadPlugin.invoke(request);
27        
28        Lead aLead = [select name, id, isConverted 
29                       from Lead where id = :testLead.ID];
30        System.Assert(aLead.isConverted);
31        
32    }
33
34     /*
35      * This tests lead conversion with 
36      * the Account ID specified.
37      */
38    static testMethod void basicTestwithAccount() {
39
40        // Create test lead
41        Lead testLead = new Lead(
42            Company='Test Lead',FirstName='John',LastName='Doe');
43        insert testLead;
44        
45        Account testAccount = new Account(name='Test Account');
46        insert testAccount;
47    
48           // System.debug('ACCOUNT BEFORE' + testAccount.ID);
49
50        LeadStatus convertStatus = [Select Id, MasterLabel 
51                    from LeadStatus where IsConverted=true limit 1]; 
52        
53        // Create test conversion
54        VWFConvertLead aLeadPlugin = new VWFConvertLead();
55        Map<String,Object> inputParams = new Map<String,Object>();
56        Map<String,Object> outputParams = new Map<String,Object>();
57
58        inputParams.put('LeadID',testLead.ID);
59        inputParams.put('AccountID',testAccount.ID);
60        inputParams.put('ConvertedStatus',
61            convertStatus.MasterLabel);
62
63        Process.PluginRequest request = new 
64            Process.PluginRequest(inputParams);
65        Process.PluginResult result;
66        result = aLeadPlugin.invoke(request);
67        
68        Lead aLead = 
69            [select name, id, isConverted, convertedAccountID 
70             from Lead where id = :testLead.ID];
71        System.Assert(aLead.isConverted);
72        //System.debug('ACCOUNT AFTER' + aLead.convertedAccountID);
73        System.AssertEquals(testAccount.ID, aLead.convertedAccountID);
74    }
75
76    /*
77     * This tests lead conversion with the Account ID specified.
78    */
79    static testMethod void basicTestwithAccounts() {
80
81        // Create test lead
82        Lead testLead = new Lead(
83            Company='Test Lead',FirstName='John',LastName='Doe');
84        insert testLead;
85        
86        Account testAccount1 = new Account(name='Test Lead');
87        insert testAccount1;
88        Account testAccount2 = new Account(name='Test Lead');
89        insert testAccount2;
90
91           // System.debug('ACCOUNT BEFORE' + testAccount.ID);
92
93        LeadStatus convertStatus = [Select Id, MasterLabel 
94            from LeadStatus where IsConverted=true limit 1]; 
95        
96        // Create test conversion
97        VWFConvertLead aLeadPlugin = new VWFConvertLead();
98        Map<String,Object> inputParams = new Map<String,Object>();
99        Map<String,Object> outputParams = new Map<String,Object>();
100
101        inputParams.put('LeadID',testLead.ID);
102        inputParams.put('ConvertedStatus',
103            convertStatus.MasterLabel);
104
105        Process.PluginRequest request = new 
106            Process.PluginRequest(inputParams);
107        Process.PluginResult result;
108        result = aLeadPlugin.invoke(request);
109        
110        Lead aLead = 
111            [select name, id, isConverted, convertedAccountID 
112            from Lead where id = :testLead.ID];
113        System.Assert(aLead.isConverted);
114    }
115
116
117     /*
118      * -ve Test
119      */    
120    static testMethod void errorTest() {
121
122        // Create test lead
123        // Lead testLead = new Lead(Company='Test Lead',
124        //   FirstName='John',LastName='Doe');
125        LeadStatus convertStatus = [Select Id, MasterLabel 
126            from LeadStatus where IsConverted=true limit 1]; 
127        
128        // Create test conversion
129        VWFConvertLead aLeadPlugin = new VWFConvertLead();
130        Map<String,Object> inputParams = new Map<String,Object>();
131        Map<String,Object> outputParams = new Map<String,Object>();
132        inputParams.put('LeadID','00Q7XXXXxxxxxxx');
133        inputParams.put('ConvertedStatus',convertStatus.MasterLabel);
134
135        Process.PluginRequest request = new 
136            Process.PluginRequest(inputParams);
137        Process.PluginResult result;
138        try {
139            result = aLeadPlugin.invoke(request);    
140        }
141        catch (Exception e) {
142          System.debug('EXCEPTION' + e);
143          System.AssertEquals(1,1);
144        }
145        
146    }
147    
148    
149     /*
150      * This tests the describe() method
151      */ 
152    static testMethod void describeTest() {
153
154        VWFConvertLead aLeadPlugin = 
155            new VWFConvertLead();
156        Process.PluginDescribeResult result = 
157            aLeadPlugin.describe();
158        
159        System.AssertEquals(
160            result.inputParameters.size(), 8);
161        System.AssertEquals(
162            result.OutputParameters.size(), 3);
163        
164     }
165
166}