[SalesForce] Error on Trigger Before Delete[Trigger.old]

The below trigger is working fine on insert and update operations but on delete it gives me the below error. can you please help me. i guess im trying to update the status__c field to inactive once contact is deleted but getting below error as in Trigger.old the values are read only can you please help me overcome this error and update the field on delete.Many Thanks

Validation Errors While Saving Record(s)
There were custom validation error(s) encountered while saving the affected record(s). The first validation error encountered was "Apex trigger Contactcallout caused an unexpected exception, contact your administrator: Contactcallout: execution of BeforeDelete caused by: System.FinalException: Record is read-only: Trigger.Contactcallout: line 11, column 1".

Click here to return to the previous page.

Trigger:-

trigger Contactcallout on Contact (after insert, after update, before delete) {
Id RecordType1= [SELECT Id FROM RecordType WHERE SOBJECTTYPE=:'Contact' AND DeveloperName=:'Commercial'].Id;
Map<Id, String> m = new Map<Id, String>();
list<Contact> validContacts = new list<Contact>();
set<ID> accIds = new set<ID>();
if(Trigger.isDelete)
    {
        for (contact c : Trigger.old) 
        {
            if(c.RecordTypeId == RecordType1 && c.Registered_on_ITV_Media__c == TRUE)    //012D0000000BaFA
            c.Status__c='Inactive';
            {
                validContacts.add(c);
                accIds.add(c.accountid);
            }   
        }
    }
    else
    {
for (contact c : Trigger.new) {
    if(c.RecordTypeId == RecordType1 && c.Registered_on_ITV_Media__c == TRUE){
    if(Trigger.isUpdate){
        contact old = Trigger.oldMap.get(c.Id);
        if (c.Email != old.Email||c.FirstName!=old.FirstName||c.LastName!=old.LastName||c.phone!=old.phone||c.Title__c!=old.Title__c||c.status__c!=old.status__c||c.AccountID!=old.AccountID||c.Registered_on_ITV_Media__c == TRUE)
    //  if (c.Email != old.Email||c.FirstName!=old.FirstName||c.LastName!=old.LastName||c.phone!=old.phone||c.Title__c!=old.Title__c||c.status__c!=old.status__c||c.AccountID!=old.AccountID)
         {
             validContacts.add(c);
                accIds.add(c.accountid);
         }
         }else{
         validContacts.add(c);
                accIds.add(c.accountid);
                }
                }
         }   
}
map<ID, Account> accMap;
if(!accIds.IsEmpty()) // guard condition for SOQL
    accMap = new map<ID, Account>([select name from account where id in :accIds]);

for (contact c : validContacts) {
    Account acc = accMap.get(c.AccountID);
    string accName = acc == null ? null : acc.Name;
    WebServiceCallout.sendNotification(c.Id,c.Email,c.FirstName,c.LastName,c.phone,c.Title__c,accName,c.status__c);
              }
}

Many Thanks in advance
Abraham

Best Answer

You can modify the values of the record before their final deletion in a Before Delete trigger event, but you need a separate DML statement for this. Example follows:

if(Trigger.isDelete) {
    Contact[] contacts = new Contact[0];
    for(Contact record: Trigger.old) {
        if(record.RecordTypeId == RecordType1 && record.Registered_on_ITV_Media__c) {
            contacts.add(new Contact(Id=record.Id, Status__c='Inactive'));
        }
    }
    update contacts;
}

Notice how I construct a new instance of the record using new Contact so it doesn't trigger the "record is read-only" error. Note that your before/after update logic will also be called, meaning the inactive status will be sent to your webservice automatically without handling this explicitly in your before delete trigger event (in other words, don't call the web service explicitly in your delete trigger event).

Related Topic