function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Steve ThurstonSteve Thurston 

How to use Apex to delete a time based workflow on Lead Conversion

I have the scenario where I am trying to convert a Lead but can't because there are pending time-based workflows.

The standard solution I come across is to create a custom checkbox field that, when it changes, causes the workflow criteria to no longer be true, and the pending workflow action quietly deletes itself.  It is then recommended that you either manually change this field value or override the conversion button to do this for you.

However, I have a complication that is preventing me from doing this.  The conversion is being triggered by a third party API call, not by a person.  So I need to have Apex change the value of this field.  And I can't get that to work.

I have tried a "before update" on the Lead, but that doesn't seem to do anything.  Investigation seems to indicate that the reason is that, before conversion, "isConverted" hasn't been set to TRUE, so I can't restrict my flag change to only conversions.

Paradoxically, I'm not sure I can use an "after update" either.  In that case, I am getting the error that I can't modify a converted Lead!  I know it is supposed to be possible to update converted Lead fields now, but I only have one User (I'm actually trying to do this in a Sandbox), and I can't modify my Profile with the necessary permission.  In any event, I'm not sure that would work either.  I think the workflow should fire after the apex code updates the field, but I'm not sure.  (And I can't test until I get the permissions sorted out.)

Surely someone has had to deal with this situation before?  To recap:

I have Leads that are getting converted by an API call.  The conversions are failing because there are pending time based workflows.  I need to use Apex to delete these time based workflows.  It must be Apex:  it cannot be done manually or via a Visualforce button.

How can this be done?

Thanks!
NagendraNagendra (Salesforce Developers) 
Hi Steve,

Please check below link from the success community which already has a solution on how to remove time-based workflow actions on lead conversion. Hope this should suffice your requirement.

Kindly mark this post as solved if the information help's so that it gets removed from the unanswered queue and becomes a proper solution which results in helping others who are really in need of it.

Best Regards,
Nagendra.P
Virendra Singh NarukaVirendra Singh Naruka
Hi Steve,

Try field update workflow action  on isConverted  to update the timebased workflow. 
Steve ThurstonSteve Thurston
Negendra:  Unfortunately, that solution is to produce a custom button.  This is all being done behind the scenes via a third party API.  That API fails when it tries to convert the Lead because there is a pending time-based workflow.  So I am trying to write a trigger that will delete (or rather, falsify and therefore remove) the workflows before the conversion attempt.  I have a custom field set up for this, but I can't get it to work.  A "before update" trigger doesn't seem to change that field's value before converting.  (i.e. it looks like the conversion takes place before the "before update" trigger, so the field doesn't get changed.)  An "after update" trigger fails because when  I try to update the triggering Lead, I get either a trigger depth error or a self-recursive error that prevents conversion.

Virendra:  See above... I can't seem to update the field on either a "before update" or "after update", unless I'm doing something wrong.

Simple test example of each (3 example triggers):

Time_Dependent_Email_Lock__c = a custom field on both the Lead and Account that defaults to TRUE (i.e. the record is locked by default.).  The Lead field is mapped to the Account field.  So after conversion, on the Account, this field value should be FALSE.


----------------------  AFTER UPDATE TRIGGER
trigger removeTimeDependentEmailAlerts on Lead (after update) {
     List<Id> triggerLeadIds = new List<Id>();
     
     for (Lead triggerLeads : trigger.New) {
          //if (triggerLeads.IsConverted == TRUE) {  // Eventually I will have to distinguish between any ol' update and a conversion.  But not now.
               triggerLeadIds.add(triggerLeads.Id);
          //}
     }

     List<Lead> theTriggerLead = [SELECT Id, Time_Dependent_Email_Lock__c FROM Lead WHERE Id IN : triggerLeadIds LIMIT 1];

     theTriggerLead[0].Time_Dependent_Email_Lock__c = FALSE;  // Change this field so that workflow conditions will be reevaluated to FALSE
     update theTriggerLead[0];  // ***The idea is to have this trigger the workflow before conversion
}

ERROR:   first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, removeTimeDependentEmailAlerts: maximum trigger depth exceeded



​----------------------  BEFORE UPDATE TRIGGER - DIRECTLY REFERENCE TRIGGER.NEW
trigger removeTimeDependentEmailAlerts on Lead (before update) {
     for (Lead triggerLeads : trigger.New) {
          //  ***NOTE:  to keep things as generic as possible, I'm not even testing for conversion here.  Just any update to the record.
          triggerLeads.Time_Dependent_Email_Lock__c = FALSE;  //  Change this field so that workflow conditions will be reevaluated to FALSE
          // ***The idea is to have this trigger the workflow before conversion
     }
}

RESULT:  Conversion happens, but when you look at the Account, the field value of Time_Dependent_Email_Lock__c has not been changed to FALSE.



​----------------------  BEFORE UPDATE TRIGGER - QUERY FOR THE LEAD AND TRY TO UPDATE IT
trigger removeTimeDependentEmailAlerts on Lead (before update) {
     List<Id> triggerLeadIds = new List<Id>();

     for (Lead triggerLeads : trigger.New) {
          triggerLeadIds.add(triggerLeads.Id);
     }

     List<Lead> theTriggerLead = [SELECT Id, Time_Dependent_Email_Lock__c FROM Lead WHERE Id IN : triggerLeadIds LIMIT 1];

     theTriggerLead[0].Time_Dependent_Email_Lock__c = FALSE;  // Change this field so that workflow conditions will be reevaluated to FALSE
     update theTriggerLead[0];  // ***The idea is to have this trigger the workflow before conversion

ERROR:  first error: SELF_REFERENCE_FROM_TRIGGER