1

I have a trigger that will look at the subject, parse out the customer number which I can match and get the Account.Id value. Once I have the value I want to update the Case.AccountId field with the Account.Id value.

The problem I have is when I do this I get 2 errors when I run a test.

System.DmlException: Update failed. First exception on row 0 with id 50018000007boyXAAQ; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CaseReassignQueueBasedOnSubject: execution of AfterUpdate

caused by: System.FinalException: Record is read-only

So I need some help to figure out if I am using the incorrect ID or the wrong after insert/before insert.

trigger CaseReassignQueueBasedOnSubject on Case (after insert) {
List<Account> lstAccount = new List<Account>();
List<Account> account = [SELECT Id, CNUM__c FROM Account];
List<Case> casesToUpdate = new List<Case>();

for (Case c: Trigger.New) {
    //validate that the parsing won't fail
    if (c.Subject.contains('[')) {
        //get CNUM
        Integer start_pos = c.Subject.indexOf('[') + 1;
        Integer end_pos = c.Subject.indexOf(']',start_pos);
        String CNUM = c.Subject.substring(start_pos,end_pos);
        System.debug('CaseReassignQueueBasedOnSubject_CNUM: ' + CNUM);
        //find the accountId
        System.debug('CaseReassignQueueBasedOnSubject_account: ' + account.size());
        for (Account la: account) {
            if (la.CNUM__c == CNUM) {
                System.debug('CaseReassignQueueBasedOnSubject_la.Id: ' + la.Id);
                System.debug('CaseReassignQueueBasedOnSubject_la.CNUM__c: ' + la.CNUM__c);
                System.debug('CaseReassignQueueBasedOnSubject_c.AccountId: ' + c.AccountId);
                c.AccountId = la.Id;
                System.debug('CaseReassignQueueBasedOnSubject_c.AccountId: ' + c.AccountId);
                casesToUpdate.add(c);
            }
        }
    }
}
if (casesToUpdate.size() > 0) {
    update casesToUpdate;
}

}

EDIT

So I have updated my code to what was suggested and came to the below. The only thing I can think of from here is this will not work for bulk inserts

trigger CaseReassignQueueBasedOnSubject on Case (after insert) {
//Get All Accounts
List<Account> account = [SELECT Id, CNUM__c FROM Account];
//Variables for later use
List<Case> casesToUpdate = new List<Case>();
String CNUM = null;
String AccountId = null;
String CaseId = null;

//For each case set variable -- Not working for bulk inserts
for (Case c: Trigger.New) {
    //validate that the parsing won't fail
    if (c.Subject.contains('[')) {
        //get CNUM
        Integer start_pos = c.Subject.indexOf('[') + 1;
        Integer end_pos = c.Subject.indexOf(']',start_pos);
        CNUM = c.Subject.substring(start_pos,end_pos);
        CaseId = c.Id;
        System.debug('Parsed_CNUM: ' + CNUM);
        casesToUpdate.add(c);
    }
}

//find the accountId and set local variable
for (Account la: account) {
   if (la.CNUM__c == CNUM) {
      System.debug('Account.Id: ' + la.Id);
      System.debug('Account.CNUM__c: ' + la.CNUM__c);
      AccountId = la.Id;
    }
}

//Update Case Values
System.debug('Case.Id: ' + CaseId);
List<Case> updateCases = [select AccountId, Id from Case where Id = :CaseId];
for (Case updC: updateCases) {
      System.debug('AccountId_NEW_SETTING_VALUE: ' + AccountId);
      updC.AccountId = AccountId;
      System.debug('updC.AccountId: ' + updC.AccountId);
}

//Update Cases
System.debug('updateCases: ' + updateCases.size());
if (updateCases.size() > 0) {
    update updateCases;
}

}

1 Answer 1

4

Your issue here is that you are trying to update the records retrieved from trigger.new in after insert of the same object, you cannot update the records this way. The records are read only in that context and thus you are getting that error.

Refer to the documentation for details. Excerpt below.

Trigger Event - after insert

Can change fields using trigger.new - Not allowed. A runtime error is thrown, as trigger.new is already saved.

Can update original object using an update DML operation - Allowed

What you will need here is to retrieve the Cases that you want to update and then perform a DML operation on those retrieved Case records.

Your code should look like something as:

List<Case> updateCases = [select <fields> from Case where <condition>];
for(Case updC : updateCases) {
    ... perform your updates ..
}

update updateCases;
8
  • In the <condition> field I would need the cases subject. to build out the la.CNUM__c == subjectCNUM What are your thoughts on this?
    – Gunner1714
    Commented Aug 24, 2018 at 14:32
  • Yes, if you want to fetch the cases based on that condition.
    – Jayant Das
    Commented Aug 24, 2018 at 14:45
  • But to get current case that is through the trigger.new? Or is there another way to get the current case?
    – Gunner1714
    Commented Aug 24, 2018 at 14:48
  • You can use the trigger.new contents to fetch the "new cases" that you want to update. But you cannot update the trigger.new contents.
    – Jayant Das
    Commented Aug 24, 2018 at 14:49
  • Okay so 2 for loops and one to get the cases then another to update. Thanks for your help
    – Gunner1714
    Commented Aug 24, 2018 at 15:31

You must log in to answer this question.

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