
I'm trying to write a trigger for Case that will reopen or uncomplete the Final Milestone in the Entitlement Process for that Case. I have run up against getting an error
FIELD_INTEGRITY_EXCEPTION, You can’t change the completion date on a case milestone that’s already exited an entitlement process.
I am using a method expanded from the milestoneUtils code found here:
https://developer.salesforce.com/page/Case_Milestones_Utilities_ClassI tried adding @future against the method and while the error no longer occurs it does not uncomplete the Milestone going from Status 'Closed' to 'Open' the first time around.However if I close the Case and then reopen subsequent times, it then does work.Can anyone offer any insight into how I may correctly use the @future annotation so that it would work first time? Or any other way of dealing with this sequence of events?This is my Trigger:
trigger openMilestoneOnReopenCase on Case (after update) {
String finalMilestone = 'Solution Time';
DateTime CompletionDate = NULL;
List<Id> cases = new List<Id>();
for(Case c:Trigger.new){
//Get the prior update Case states
Case oldCaseState = Trigger.oldMap.get(c.Id);
// Checking if this is a Case being reopend from Closed
if(c.Status == 'Open' && oldCaseState.Status == 'Closed'){
// Get the Case Milestone List
List<CaseMilestone> caseMilestones = [Select MilestoneTypeId, IsCompleted from CaseMilestone cm where cm.MilestoneType.Name=:finalMilestone AND cm.CaseId=:c.Id];
//Iterate the Case Milestone List
for(CaseMilestone caseMilestone:caseMilestones){
//Check the Solution Time state isCompleted and add the Case to the Case List
if(caseMilestone.isCompleted == true){
cases.add(c.Id);
}
}
// Call the milestoneUtils Method
if(!cases.isEmpty()){
milestoneUtils.reopenMilestone(cases, finalMilestone, completionDate);
}
}
}
}
This is the milestonesUtil Class I am calling the method from:
ThanksPatrickpublic class milestoneUtils {
@future
public static void reopenMilestone(List<Id> caseIds, String milestoneName, DateTime complDate) {
System.debug('ASPD DEBUG: milestoneUtils: DateTime for completeMilestone is ' + string.valueOfGMT(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;
}
}
}

I got some time to look through this again and I was possibly hasty. The @future method does appear to work. Sometimes I need to refresh the page to see the Milestone uncompleted though. I guess there can be a little bit of a time delay.@ilewi121I just wrote some code to have our First response time Milestone automatically completed on Case creation if the source if an inbound phone call. I had to use the @future method for that also. Some similar Apex should probably work for youCan't seem to post with code tags though