[SalesForce] Apex Trigger to update Account field when Case field is updated

I am struggling to come up with a trigger to update an Account field (Last Survey Sent) when the same field gets inserted or updated on the Case (Last Survey Sent). I am unable to do this via workflow. Any help?

Survey gets sent -> Last Survey Sent field on Case is updated to TODAY() -> Last Survey Sent field on its Account gets set to the same date as the Last Survey Sent field on the Case.

Thanks,
Brian

Best Answer

You could use the following trigger code to keep the two in sync. Rename the Last Survey Sent to match your API name.

Trigger CaseAfterInsertUpdate on Case (after insert, after update) {
    List<Account> accList = new List<Account>();
    for (Case c : Trigger.new) {
        Account acc = new Account(
            Id = c.Account.Id,
            Last_Survey_Sent__c = c.Last_Survey_Sent__c
        );
        accList.add(acc);
    }
    try {
        update accList;
    } catch (Exception ex) {
        System.debug('Could not update Last Survey Sent field on Account with cause: ' + ex.getCause())
    }
}

And the test class. This assumes that the Last Survey Sent field is writable on the Case object.

@isTest
private class CaseTriggerTests() {
    @isTest static void testLastSurveySent() {
        // Insert Account and Case for tests
        // These may need additional fields, depending on your organization
        Account acc = new Account(
           Name = 'Test Account',
           Website = 'www.test.com',
           Phone = '8888888888'
        );
        insert acc;
        Case c = new Case(
            Account = acc.Id,
            Last_Survey_Sent__c = Date.Today();
        );
        insert c;
        // Test that the Last Survey Sent field on the account was updated on Insert
        Account accTest = [SELECT Id, Last_Survey_Sent__c FROM Account WHERE Id = :acc.id];
        System.assertEquals(accTest.Last_Survey_Sent__c, Date.Today());
        // Test that the Last Survey Sent field on the account changes on Update
        c.Last_Survey_Sent__c = Date.Today()+1;
        update c;
        accTest = [SELECT Id, Last_Survey_Sent__c FROM Account WHERE Id = :acc.id];
        System.assertEquals(accTest.Last_Survey_Sent__c, Date.Today()+1);
    }
}

While it may seem more intuitive to query for the account, the use of new and then setting the ID protects you during bulk updates. If you had 1000 cases to update at once, it would require 1000 SOQL queries. Also note that I am adding the accounts to a list and updating the entire list after the trigger runs its for loop. That's another technique for 'bulkifying' and protects against exceeding DML limits.

Let me know if you have any other questions. I would be happy to walk you through writing unit tests for this trigger.