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
Ratheven SivarajahRatheven Sivarajah 

I am writing a trigger Where I close my milestone But I am receiving a recursively update itself: []

Hey everyone I have 3 independent milestone that get activated based on the status of the case. I am writing a trigger to close whichever mileston was activated before the case status is changed to closed. Thank you for your help!!

----------------Trigger------------------
trigger MilestoneCompleteTrigger on Case (before update, after update) {
    DateTime completionDate = System.now();
    List<Id> updateCases = new List<Id>();
        for(Case c: Trigger.new){ 
        if(c.Status == 'Closed'){
        updateCases.add(c.Id);
            }           
            if (updateCases.isEmpty() == false){
                for(Case cases: Trigger.old){ 
                      
             if(cases.Status == 'New'){
                milestoneUtils.completeMilestone(updateCases, 'First Response', completionDate); 
                 
             } else if(cases.Status != 'Awaiting Customer Response' || cases.Status != 'Customer Follow-Up Required'){
                 milestoneUtils.completeMilestone(updateCases, 'In our hands', completionDate); 
                 
             } else {
                 milestoneUtils.completeMilestone(updateCases, 'In the Customer hands', completionDate); 
             }
           }
          }
        }
}

----------Apex class-----------------
public class MilestoneUtils {
    public static void completeMilestone(List<Id> caseIds, 
            String milestoneName, DateTime complDate) {  
    List<CaseMilestone> cmsToUpdate = [select Id, completionDate
            from CaseMilestone cm
            where caseId in :caseIds and cm.MilestoneType.Name=:milestoneName 
            and completionDate = null limit 1];
    if (cmsToUpdate.isEmpty() == false){
        for (CaseMilestone cm : cmsToUpdate){
            cm.completionDate = complDate;
            }
        update cmsToUpdate;
        }
    }
}
--------------------The error I am recieving is -----------------
MilestoneCompleteTrigger: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0 with id 5556C000000QjtEQAS; first error: SELF_REFERENCE_FROM_TRIGGER, Object (id = 5006C00000ACcUO) is currently in trigger MilestoneCompleteTrigger, therefore it cannot recursively update itself: [] Class.MilestoneUtils.completeMilestone: line 12, column 1 Trigger.MilestoneCompleteTrigger: line 15, column 1
Prateek Prasoon 25Prateek Prasoon 25
Here is an updated version of your trigger that should avoid the recursion error:
trigger MilestoneCompleteTrigger on Case (before update) {
    DateTime completionDate = System.now();
    List<Id> updateCases = new List<Id>();
    for (Case c: Trigger.new) {
        if (c.Status == 'Closed' && Trigger.oldMap.get(c.Id).Status != 'Closed') {
            updateCases.add(c.Id);
            if (c.Status == 'Closed' && updateCases.size() > 0) {
                List<CaseMilestone> cmsToUpdate = [SELECT Id, completionDate
                    FROM CaseMilestone
                    WHERE caseId IN :updateCases
                    AND milestoneType.Name IN ('First Response', 'In our hands', 'In the Customer hands')
                    AND completionDate = null];
                for (CaseMilestone cm : cmsToUpdate) {
                    if (cm.MilestoneType.Name == 'First Response') {
                        MilestoneUtils.completeMilestone(cm, completionDate);
                    } else if (cm.MilestoneType.Name == 'In our hands') {
                        MilestoneUtils.completeMilestone(cm, completionDate);
                    } else if (cm.MilestoneType.Name == 'In the Customer hands') {
                        MilestoneUtils.completeMilestone(cm, completionDate);
                    }
                }
            }
        }
    }
}

And here is the updated MilestoneUtils class:
public class MilestoneUtils {
    public static void completeMilestone(CaseMilestone cm, DateTime complDate) {  
        cm.completionDate = complDate;
        update cm;
    }
}

If you find this answer helpful, please mark it as the best answer.