so basically I ripped off http://www.iterativelogic.com/using-invocable-methods-with-skuid/ in order to integrate an automatic Lead Convert Method that can be called from Skuid and I'm unable to test it.
The InvocableMethod is:
global class LeadConvertAction {
@InvocableMethod(label='Convert Leads')
global static List<ConvertLeadActionResult> convertLeads(List<ConvertLeadActionRequest> requests) {
List<ConvertLeadActionResult> results = new List<ConvertLeadActionResult>();
try {
for (ConvertLeadActionRequest request : requests) {
results.add(convertLead(request));
}
}
catch(Exception ex) {
System.debug(ex);
}
System.debug(results);
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);
}
try {
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());
}
}
catch(Exception ex) {
ConvertLeadActionResult result = new ConvertLeadActionResult();
result.error = ex.getMessage();
return result;
}
}
global class ConvertLeadActionRequest {
@InvocableVariable(required=true)
public ID leadId;
@InvocableVariable(required=true)
public String convertedStatus;
@InvocableVariable
public ID accountId;
@InvocableVariable
public ID contactId;
@InvocableVariable
public Boolean overWriteLeadSource;
@InvocableVariable
public Boolean createOpportunity;
@InvocableVariable
public String opportunityName;
@InvocableVariable
public ID ownerId;
@InvocableVariable
public Boolean sendEmailToOwner;
}
global class ConvertLeadActionResult {
@InvocableVariable
public ID accountId;
@InvocableVariable
public ID contactId;
@InvocableVariable
public ID opportunityId;
@InvocableVariable
public String error;
}
class ConvertLeadActionException extends Exception {}
}
And then my testClass as of now is:
@isTest
global class LeadConvertActionTest {
private static testMethod void doTest() {
Test.startTest();
Lead l = new Lead(FirstName = 'TestFirst',
LastName = 'TestLast',
Street = 'Somewhere',
City = 'Around',
State = 'CA',
PostalCode = '90002',
Phone = '3103081233',
Email = '[email protected]',
Existing_PV_System__c = 'Yes',
Utility__c = 'Other');
insert l;
//String jsonInput = '{"leadId": "' + l.Id + '", "convertedStatus": "Closed - Converted"}';
//String jsonInput = '{"inputs":[{"leadId": "' + l.Id + '", "convertedStatus": "Closed - Converted"}]}';
//Map<String, Object> leadObj = (Map<String, Object>)JSON.deserializeUntyped(jsonInput);
//Map<String, Object> leadObj = (Map<String, Object>)JSON.deserializeStrict(jsonInput, String.class);
//Map<String, String> MyStrings = new Map<String, String>{'leadId' => l.Id, 'convertedStatus' => 'Closed - Converted'};
//new Object { 'leadId' => l.Id, 'convertedStatus' => 'Closed - Converted' }
List<LeadConvertAction.ConvertLeadActionRequest> leadC = New List<LeadConvertAction.ConvertLeadActionRequest>();
//leadC.leadId = new ID l.Id;
leadC.leadId = l.Id;
leadC.convertedStatus = 'Closed - Converted';
List<LeadConvertAction.ConvertLeadActionResult> converted = LeadConvertAction.convertLeads(leadC);
Test.stopTest();
Account a = [Select FirstName, LastName, Id From Account where ID = :converted.accountId];
Contact c = [Select FirstName, LastName, Id From Contact where ID = :converted.contactId];
Opportunity o = [Select Account.FirstName, Account.LastName, Id From Opportunity where ID = :converted.opportunityId];
system.assertEquals(a.FirstName, l.FirstName);
system.assertEquals(c.LastName, l.LastName);
system.assertEquals(o.Account.LastName, l.LastName);
}
}
The different json strings and maps were my futile attempts at making the object correct but I keep getting:
I've tried many solutions but can solve it. The last errors I'm getting are:
Error: Compile Error: Initial term of field expression must be a concrete SObject: List<LeadConvertAction.ConvertLeadActionRequest> at line 28 column 9
Now the error is quite obvious, but I'm not sure why it's happening. I've also try to create the leadC.leadId field as a new ID but a whole different range of errors appear, from cannot be initiated as an ID etc. Before I tried simply parsing, encoding, creating a List, and passing that directly to the function Call, but was always getting type mismatches so decided to initialize the variables with News and try to set their values and then pass it...
In the real usage, it will be called from a JS snippet as:
var request = '{"inputs":[{"leadId": "' + row.Id + '", "convertedStatus": "Closed - Converted"}]}';
console.log(request);
$.ajax('/services/data/v33.0/actions/custom/apex/LeadConvertAction', {
data: request,
type: 'POST',
crossDomain: true,
dataType: "json",
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + sforce.connection.sessionId);
xhr.setRequestHeader('Content-Type', 'application/json');
},
...
If anyone can help would be greatly appreciated! Thanks Micael