Lead management is one of the most sensitive areas in any Salesforce org. Whether you’re a growing startup or an enterprise-level business, losing a qualified or active lead due to accidental deletion can mean lost revenue, broken workflows, and incomplete sales cycles. Similarly, when new leads are created, it’s critical to ensure prompt follow-up to maximize conversion potential.
In this blog, you’ll explore a dual-purpose Apex trigger for the Lead object that ensures:
-
Users cannot delete Leads marked as “Working-Contacted”
-
A Task is automatically created for every new Lead, reminding sales reps to follow up
This trigger enforces data protection for active Leads while simultaneously driving proactive engagement—two goals that are key to a healthy sales pipeline.
🧠 Why This Trigger Matters
Leads marked as "Working-Contacted"
typically represent contacts that have shown some level of interest and are currently in communication. Deleting such leads—even by accident—can be costly. By using Apex to prevent deletion based on status, you can ensure only non-active or irrelevant leads are removed, while in-progress deals remain protected.
On the flip side, timely lead follow-ups often make or break conversions. With this trigger, every new Lead gets a related Task assigned automatically, reinforcing a culture of consistent follow-up without relying on reps to remember or manually log next steps.
Together, this Apex logic addresses two common business needs: data integrity and sales discipline.
🔍 What You’ll Learn in This Blog
-
How to prevent the deletion of active leads using Apex
-
How to conditionally enforce business rules with
addError()
-
How to automate task creation on Lead insert
-
The value of using before delete and after insert trigger contexts effectively
-
How to structure Apex logic using handler classes for readability and maintainability
-
Why proactive automation improves both lead quality and conversion rates
This is an ideal real-world example of how Apex triggers can enforce data protection rules while also supporting sales workflows automatically, all without requiring Flows, validation rules, or manual intervention.
🎯 Use Cases Where This Applies
-
B2B sales orgs where qualified leads should never be deleted
-
Call center or outbound sales environments that track lead statuses
-
Organizations where follow-up is critical to customer acquisition
-
Teams that want to automate early-stage engagement while maintaining record control
-
Salesforce admins looking to hard-code safety nets against accidental data loss
This kind of logic can easily be extended or customized further—for example, preventing deletions based on other statuses like “Qualified” or “Converted,” or assigning different follow-up tasks based on the Lead source or record type.
👨💻 Developer & Admin Tips
You can configure the Task’s priority, subject, and description using Custom Metadata or Custom Labels to make the automation adaptable across business units. Also, always write comprehensive test classes for triggers that involve DML operations in both before
and after
contexts.
While this solution currently handles Leads, the same pattern can be replicated across objects like Opportunities, Cases, or custom objects to automate safety and workflow processes.
🎥 Visual Learner? Check the YouTube Playlist
We’ve included a YouTube playlist that visually demonstrates this scenario. You’ll see how to write the code, test it in a sandbox, and understand the impact it has on your business processes. Whether you’re a developer learning Apex or an admin looking to harden your sales pipeline, this video series makes it simple to follow along.
Solution:
public class LeadTriggerHandler {
public static void handleActivitiesBeforeDelete (List<Task> leadRecords) {
for (Lead leadRec : leadRecords) {
System.debug(‘Found a lead’);
System.debug(leadRec.Status);
if (leadRec.Status == ‘Working-Contacted’) {
System.debug(‘Yes, it is in progress’);
leadRec.addError(‘You cannot delete a Lead in progress’);
}
}
}
public static void handle ActivitiesAfterInsert (List leadRecords) {
List taskListToInsert = new List ();
for (Lead leadRec : leadRecords) {
Task taskRecord = new Task();
taskRecord.Priority = ‘High’;
taskRecord.OwnerId = leadRec.OwnerId;
taskRecord.Description = ‘Follow up with the new lead’;
taskRecord.Status = ‘Not Started’;
taskRecord.Subject = ‘Follow up’;
taskRecord.WhoId = leadRec.Id;
taskListToInsert.add(taskRecord);
}
if(!taskListToInsert.isempty()){
insert taskListToInsert;
}