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
PriscillaO_PriscillaO_ 

trigger to create a note when lead status changes

I've never written an apex code before, could you please help me with writing one that triggers to create a note in the Leads page whenever the lead status is changed? This way the User won't be able to save the lead until they create a note about the status change. Thank you!
Best Answer chosen by PriscillaO_
Jain NileshJain Nilesh
Here's the code you can refer too :

I have assumed that your Sales Team would be Updating the title on Notes as the New Status, You will need to decide on the mechanism of Identifying Related notes with Status change and hence I have assumed you will be storing the Status in the title. Feel free to change the logic as per your requirement.

trigger leadStatusChange on Lead (before update) 
{
    leadStatusChangeHandler objHandler = new leadStatusChangeHandler();
    
    if(Trigger.isUpdate && Trigger.isBefore)
        objHandler.validateStatus(Trigger.new, Trigger.oldMap);
    
}

public with sharing  class leadStatusChangeHandler
{
    public final String strAddError = 'Please Create a Note Record';
    public leadStatusChangeHandler(){
    }
    
    public void validateStatus(List<Lead> newLeadList, Map<Id, Lead> oldLeadMap)
    {
        Map<String, String> mapLeadNotes = fetchNotes(newLeadList);
        for(Lead objLead : newLeadList)
        {
            if(oldLeadMap.get(objLead.Id).Status != objLead.Status)
            {
                if(mapLeadNotes == null || !mapLeadNotes.containsKey(objLead.Id) || !mapLeadNotes.get(objLead.Id).containsIgnoreCase(objLead.Status))
                    objLead.addError(strAddError);
            }
        }
    }
    
    public Map<String, String> fetchNotes(List<Lead> newLeadList)
    {
        Map<String, String> mapNotes = new Map<String, String>(); 
        for(Note objNote : [Select Id, Title, ParentId from Note where ParentId IN : newLeadList Order by CreatedDate DESC])
        {
            if(mapNotes != null && !mapNotes.containsKey(objNote.ParentId))
                mapNotes.put(objNote.ParentId, objNote.Title);
        }
        return mapNotes;
    }
    
}

Don't forget to mark it as 'Best Answer' if it has resolved your query.

Thanks!

All Answers

Jain NileshJain Nilesh

@ERP 5 : Whenever there is a status change on Lead do you want to create Note object's record or update Note field in Leads object?
PriscillaO_PriscillaO_
I'd like to create a Note object's record, thanks.
Jain NileshJain Nilesh
triggers to create a note in the Leads page whenever the lead status is changed?
This way the User won't be able to save the lead until they create a note about the status change.

The above 2 points seem to be confusing, Do you want to automate creation of Note's object record with some default values via Trigger when the lead status is changed or do you want to add Error on the leads page when the Note record is not present for the Status changed.
PriscillaO_PriscillaO_
I'm sorry I wasn't clear, I want to add Error on the leads page when the Note record is not present for the Status changed.
Jain NileshJain Nilesh
Here's the code you can refer too :

I have assumed that your Sales Team would be Updating the title on Notes as the New Status, You will need to decide on the mechanism of Identifying Related notes with Status change and hence I have assumed you will be storing the Status in the title. Feel free to change the logic as per your requirement.

trigger leadStatusChange on Lead (before update) 
{
    leadStatusChangeHandler objHandler = new leadStatusChangeHandler();
    
    if(Trigger.isUpdate && Trigger.isBefore)
        objHandler.validateStatus(Trigger.new, Trigger.oldMap);
    
}

public with sharing  class leadStatusChangeHandler
{
    public final String strAddError = 'Please Create a Note Record';
    public leadStatusChangeHandler(){
    }
    
    public void validateStatus(List<Lead> newLeadList, Map<Id, Lead> oldLeadMap)
    {
        Map<String, String> mapLeadNotes = fetchNotes(newLeadList);
        for(Lead objLead : newLeadList)
        {
            if(oldLeadMap.get(objLead.Id).Status != objLead.Status)
            {
                if(mapLeadNotes == null || !mapLeadNotes.containsKey(objLead.Id) || !mapLeadNotes.get(objLead.Id).containsIgnoreCase(objLead.Status))
                    objLead.addError(strAddError);
            }
        }
    }
    
    public Map<String, String> fetchNotes(List<Lead> newLeadList)
    {
        Map<String, String> mapNotes = new Map<String, String>(); 
        for(Note objNote : [Select Id, Title, ParentId from Note where ParentId IN : newLeadList Order by CreatedDate DESC])
        {
            if(mapNotes != null && !mapNotes.containsKey(objNote.ParentId))
                mapNotes.put(objNote.ParentId, objNote.Title);
        }
        return mapNotes;
    }
    
}

Don't forget to mark it as 'Best Answer' if it has resolved your query.

Thanks!
This was selected as the best answer
PriscillaO_PriscillaO_
Thanks Jain, I assume this is to be run in "apex test execution", is that correct?
I paste your code and got a few problems: line 9 missing " at 'public'
line 2 invalid type: leadStatusChangeHandler
line 5 Variable does not exist: objHandler
 
Jain NileshJain Nilesh
So copy this part under lead trigger : trigger leadStatusChange on Lead (before update) { leadStatusChangeHandler objHandler = new leadStatusChangeHandler(); if(Trigger.isUpdate && Trigger.isBefore) objHandler.validateStatus(Trigger.new, Trigger.oldMap); } Step 2 : Under Setup type Apex class and create new Apex class : Paste the below code : public with sharing class leadStatusChangeHandler { public final String strAddError = 'Please Create a Note Record'; public leadStatusChangeHandler(){ } public void validateStatus(List newLeadList, Map oldLeadMap) { Map mapLeadNotes = fetchNotes(newLeadList); for(Lead objLead : newLeadList) { if(oldLeadMap.get(objLead.Id).Status != objLead.Status) { if(mapLeadNotes == null || !mapLeadNotes.containsKey(objLead.Id) || !mapLeadNotes.get(objLead.Id).containsIgnoreCase(objLead.Status)) objLead.addError(strAddError); } } } public Map fetchNotes(List newLeadList) { Map mapNotes = new Map(); for(Note objNote : [Select Id, Title, ParentId from Note where ParentId IN : newLeadList Order by CreatedDate DESC]) { if(mapNotes != null && !mapNotes.containsKey(objNote.ParentId)) mapNotes.put(objNote.ParentId, objNote.Title); } return mapNotes; } } Thanks!
PriscillaO_PriscillaO_
Hi Jain, sorry for the late reply. I still get an error when trying to save the lead trigger. I paste everything in line 1.
trigger leadStatusChange on Lead (before update) { leadStatusChangeHandler objHandler = new leadStatusChangeHandler(); if(Trigger.isUpdate && Trigger.isBefore) objHandler.validateStatus(Trigger.new, Trigger.oldMap); }
Error: Compile Error: Invalid type: leadStatusChangeHandler at line 1 column 52
 
PriscillaO_PriscillaO_
on step 2 - creating a new apex class, i also get an error.
Error: Compile Error: Missing '<' at 'newLeadList' at line 1 column 186
Jain NileshJain Nilesh
Please connect with me on Linkedin, I will be happy to help after few queries.