I need to mark the CaseMilestone as complete and populate the completion date, when the owner of it's parent Case is changed.

For other objects I can use

List<Account> acctsToUp = new list<Account>();
for(Entitlement e:entitlements){

    Account a = new Account(Id = e.AccountId);

to create a list of Accounts and then update the Account fields (I'm new to Apex and although I know the outcome of using this code, I'm not sure exactly what's happening there).

When I try to do the same in the below code, it causes an error

Field is not writeable: CaseMilestone.CaseId

and I realise that this Id can't be updated whereas the Account's can but I'm not sure what the alternative is?

When selecting the CaseMilestone(s) to update, I need to check that their MilestoneTypeId matches the Id fetched by the SOQL query.

trigger completeMilestoneOnAssignment on Case (after update) {

    List<WEID__c> weids = WEID__c.getall().values();
    Set<Id> validRecordTypeIds = new Set<Id>();

        for (WEID__c weid: weids) {
        try {
            } catch (System.StringException e) {
                'Invalid Record Type Id ' + weid.WECaseId__c

    List<Id> caseIds = new List<Id>();
    for (Case c : Trigger.new){

            Case oldCase = Trigger.oldMap.get(c.Id);
            if(oldCase != null && oldCase.OwnerId != c.OwnerId &&

    if(caseIds.isEmpty() == false){

        List<MilestoneType> milestoneId = [SELECT Id
                                        From MilestoneType
                                        Where Name = 'Case Accepted'];
        if(milestoneId.isEmpty() == false){

            List<CaseMilestone> milestonesToUp = new List<CaseMilestone>();
            for (Case c:caseIds){

                CaseMilestone m = new CaseMilestone(CaseId = c.Id);
                m.IsCompleted = TRUE;
                m.CompletionDate = System.now();


            update milestonesToUp;

1 Answer 1


I think the issue is that you are trying to update caseId rather than Id on CaseMilestone. It may be because Case - CaseMilestone is a Master detail type relationship and you are not allowed to change it. As an alternative what you could do is

//Query for CaseMilestones using your CaseIds
List<CaseMilestone> cms = [select Id,Name from CaseMilestone where CaseId=:caseIds AND MilestoneTypeId = :caseAcceptedId];
//loop through them and set completed date etc
for(CaseMilestone cm : cms){
    cm.CompletionDate = System.now();

//then update the caseMilestones
update cms;
  • 1
    I've just found out that IsCompleted can't be edited by Apex see this post salesforce.stackexchange.com/questions/1729/…. I'll suggest an edit for your answer to include AND MilestoneTypeId = :caseAcceptedId] for other user's benefit. Thanks Ranga!
    – Alex S
    Commented May 17, 2015 at 19:44
  • Nice one. Thanks for sharing :) I've updated the snippet as you suggested
    – Ranga
    Commented May 17, 2015 at 19:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .