+ Start a Discussion
Peter CowenPeter Cowen 

Error on trigger when deleting account

I have a trigger that uses the account name to populate the service contract on the case. I have come across a few instances where we need to change the contact and account on the case so we delete the following off the case:
1. Service Contract
2. Account
3. Contact (then add a new contact)
Once I press save it errors with caused an unexpected exception, contact your administrator: Trigger: execution of AfterUpdate caused by: System.FinalException:Record is read-only: Trigger. Trigger line 9,column 1

The trigger is
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
trigger UpdateServiceContract on Case (before insert,before update, after update) {
  Id caseRecordTypeId = [Select id from RecordType where sObjectType = 'Case' and developerName ='Service_Desk' ].id ; 
    for (Case c : trigger.new) {
    if (c.RecordTypeID == caseRecordTypeId )
      if (c.service_contract__c == NULL){
        try{
          //c.Service_Contract__c = [select Id from ServiceContract where AccountId ='810D0000000Cfza' and Primary_Service_Contract__c = True].id;
        c.Service_Contract__c = [select Id from ServiceContract where AccountId = :c.AccountId and Primary_Service_Contract__c = True limit 1].id;
        }catch(QueryException e) {
          //No records found. Maybe you should set it to Null
      }
     }
    }
  
}

How do I amend the trigger to accomadate for the deletion of an account and service contract and a new contact is added?
VIVEK 998VIVEK 998
Please work on it before update/before insert as you can minimize the DML used by following this rule.
DebasisDebasis
Hi Peter,


please try below code
trigger UpdateServiceContract on Case (before insert,before update) {
  Id caseRecordTypeId = [Select id from RecordType where sObjectType = 'Case' and developerName ='Service_Desk' ].id ;
	map<id,id> caseaccAndServiceContractMap = new map<id,id> ();
	set<id> caseAccountidSet = new set<id>();
	for(case c:trigger.new){
		caseAccountidSet.add(c.AccountId);
	}
	if(caseAccountidSet.size()>0){
		for(ServiceContract sc : [select Id,AccountId from ServiceContract where AccountId in:caseAccountidSet and Primary_Service_Contract__c = True ){
			caseaccAndServiceContractMap(sc.AccountId,sc.id);
		}
	}
    for (Case c : trigger.new) {
    if (c.RecordTypeID == caseRecordTypeId ){
      if (c.service_contract__c == NULL){
        try{
         if(caseaccAndServiceContractMap.get(c.Accountid)!=null){
			  c.Service_Contract__c = caseaccAndServiceContractMap.get(c.Accountid);
		 }
       
        }catch(QueryException e) {
          //No records found. Maybe you should set it to Null
      }
     }
    }
	}
  
}

let me know if it helps you.

Thanks,
Debasis
Yury BondarauYury Bondarau
Hi Peter,

Please remove after update in trigger definition (1st line). The exception says: You can not set field value if record already updated (after update context)

1st line of code should looks like :
trigger UpdateServiceContract on Case (before insert,before update) {

PS.
Please note in salesforce this is a one of deadly sin to execure SQL inside loops
DebasisDebasis
Hi Peter,

I have modified your trigger to not execute soql inside forloop and also your System.FinalExceptio handeled as this trigger execute in before event. please execute and check it.
trigger UpdateServiceContract on Case (before insert,before update) {
  Id caseRecordTypeId = [Select id from RecordType where sObjectType = 'Case' and developerName ='Service_Desk' ].id ;
	map<id,id> caseaccAndServiceContractMap = new map<id,id> ();
	set<id> caseAccountidSet = new set<id>();
	for(case c:trigger.new){
		caseAccountidSet.add(c.AccountId);
	}
	if(caseAccountidSet.size()>0){
		for(ServiceContract sc : [select Id,AccountId from ServiceContract where AccountId in:caseAccountidSet and Primary_Service_Contract__c = True ){
			caseaccAndServiceContractMap(sc.AccountId,sc.id);
		}
	}
    for (Case c : trigger.new) {
    if (c.RecordTypeID == caseRecordTypeId ){
      if (c.service_contract__c == NULL){
        try{
         if(caseaccAndServiceContractMap.get(c.Accountid)!=null){
			  c.Service_Contract__c = caseaccAndServiceContractMap.get(c.Accountid);
		 }
       
        }catch(QueryException e) {
          //No records found. Maybe you should set it to Null
      }
     }
    }
	}
  
}

please do let me know if it helps you.


Thanks,
Debasis