I have a trigger that converts Leads to Opportunities. The trigger fires after update on the Lead object when the Lead Status changes to "Contacted/Qualified" (the "Converted" value). This update to the Lead Status happens in another trigger which fires after update on the Task object. The flow is like this:
- User creates a Lead, a Task is automatically generated
- When that Task's Status is updated to "Completed", another Task is created and the Lead Status is updated from "Raw" to "Checked".
- When that second Task's Status is changed to "Completed", the Lead Status is set to "Contacted/Qualified", which starts the Lead conversion process using the LeadConvert class.
All of this tests flawlessly, and works flawlessly in Lightning Experience. For some reason though, in Salesforce Classic, something different happens, even with the same user.
When trying to update the Status of the second Task described above to "Completed", instead of updating the Status and converting the Lead as expected, it sends me to a page that says "This lead has been converted." with a link to return to the previous page, but then when I check the Lead, the Status has not updated and no Opportunity has been created.
Does anyone know of any documented reason for this difference in behavior, or a workaround?
Edit: Adding the code for the Trigger that is not being successful. I noticed while posting this code here that there was an extra character at the end of my email address I'm reporting errors to, so I'm going to dig into that in the meantime (Update here, I fixed the email and it's still not reporting any errors).
trigger ConvertContactedLeadsToOpportunitiesTrigger on Lead (after update) {
List<Lead> preUpdateLeads = Trigger.old;
List<Lead> postUpdateLeads = Trigger.new;
Integer leadIndex = 0;
for(Lead postUpdateLead : postUpdateLeads) {
Lead preUpdateLead = preUpdateLeads[leadIndex];
if(preUpdateLead.Status != 'Contacted/Qualified' && postUpdateLead.Status == 'Contacted/Qualified') {
//Converted lead -> opp
Database.LeadConvert leadConvertObject = new Database.LeadConvert();
leadConvertObject.setLeadId(postUpdateLead.Id);
LeadStatus convertStatus = [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true AND MasterLabel = 'Contacted/Qualified' LIMIT 1];
leadConvertObject.setConvertedStatus(convertStatus.MasterLabel);
leadConvertObject.setOpportunityName('Sales Opportunity');
leadConvertObject.setAccountId(postUpdateLead.Account_Name__c);
leadConvertObject.setContactId(null);
Database.LeadConvertResult leadConvertResult = Database.convertLead(leadConvertObject);
if(leadConvertResult.isSuccess() == false) {
EmailMessageHelper emh = new EmailMessageHelper();
emh.addLine('Error converting Leads to Opportunities:');
emh.addLine('');
for(Database.Error dbError : leadConvertResult.getErrors()) {
emh.addLine(dbError.getMessage());
}
Mailer mailer = new Mailer(emh.getEmailMessage(), 'Error Converting Lead to Opp', new String[] {'[email protected]'});
mailer.sendEmail();
}
}
leadIndex += 1;
}
}
Here is the test class as well which is passing in the same environment I'm manually testing where I receive the error described above:
@isTest
public class ConvertContactedLeadsToOppsTestClass {
public static testMethod void test_contacted_qualified_leads_are_converted_to_opportunities_and_have_follow_up_tasks_created() {
Profile profileId = [SELECT Id FROM Profile WHERE Name = 'Sales User' LIMIT 1];
UserRole profileRole = [SELECT Id FROM UserRole WHERE Name = 'Sales Solutions'];
User testUser = new User(
LastName = 'User',
FirstName='Rob',
Alias = 'ruser',
Email = '[email protected]',
Username = 'rob.user'+String.valueOf(DateTime.now().getTime())+'@company.com',
ProfileId = profileId.Id,
UserRoleId = profileRole.Id,
TimeZoneSidKey = 'GMT',
LanguageLocaleKey = 'en_US',
EmailEncodingKey = 'UTF-8',
LocaleSidKey = 'en_US'
);
insert testUser;
testUser = [SELECT Id FROM User WHERE Email = 'rusert[email protected]' LIMIT 1];
System.runAs(testUser) {
Test.startTest();
Account testAccount = new Account(Name = 'Test Account');
insert testAccount;
testAccount = [SELECT Id FROM Account WHERE Name = 'Test Account' LIMIT 1];
Lead testLead = new Lead(
OwnerId = testUser.Id,
Account_Name__c = testAccount.Id,
FirstName = 'Lead',
LastName = 'Leaderson',
Company = 'Lead Inc.'
);
insert testLead;
testLead = [SELECT Status FROM Lead WHERE LastName = 'Leaderson'];
System.assertEquals('Raw', testLead.Status);
Task eligibilityCheckTask = [SELECT ActivityDate, Status, OwnerId, WhatId, Subject FROM Task WHERE OwnerId =: testUser.Id AND Subject = 'Eligibility Check' LIMIT 1];
eligibilityCheckTask.Status = 'Completed';
update eligibilityCheckTask;
Task sendCampaignEmailTask = [SELECT ActivityDate, Status, OwnerId, WhatId, Subject FROM Task WHERE OwnerId =: testUser.Id AND Subject = 'Send Campaign Email' LIMIT 1];
sendCampaignEmailTask.Status = 'Completed';
update sendCampaignEmailTask;
Test.stopTest();
Opportunity msOpportunity = [SELECT Name, StageName, RecordTypeId, CloseDate FROM Opportunity WHERE OwnerId =: testUser.Id LIMIT 1];
Task followUpTask = [SELECT ActivityDate, Status, OwnerId, WhatId, Subject FROM Task WHERE OwnerId =: testUser.Id AND Subject = '7 Day Followup' LIMIT 1];
testLead = [SELECT Status FROM Lead WHERE LastName = 'Leaderson' LIMIT 1];
RecordType msRecordType = [SELECT Id FROM RecordType WHERE SobjectType = 'Opportunity' AND Name = 'Sales Record Type' LIMIT 1];
System.assertEquals('Contacted/Qualified', testLead.Status);
System.assertEquals(Date.today().addDays(7), followUpTask.ActivityDate);
System.assertEquals(msRecordType.Id, msOpportunity.RecordTypeId);
System.assertEquals('Sales Opportunity', msOpportunity.Name);
System.assertEquals(Date.today().addDays(30), msOpportunity.CloseDate);
System.assertEquals('Reached Out', msOpportunity.StageName);
}
}
}