After Insert/Update/Undelete/Delete handling
The “After” trigger handlers should be used to modify all records related to the Trigger Context like parent or child records or totally not related data but we should try not to touch Trigger Context. After trigger are also the best place to request for Asynchronous Apex code execution
Simple custom rollup calculation step
To create a simple rollup calculation on Account when a new Contact is created. First we need to create an after insert trigger on Contact. Simply use Generate Trigger Code and deploy the trigger. Next create the class below and register trigger config as it was done previously with news constructed elements.
1public with sharing class CountEmployeesStep extends forvendi.Step {
2
3
4 private final Set<Id> accountIds = new Set<Id>();
5
6
7 public CountEmployeesStep() {
8 super(CountEmployeesStep.class.getName());
9 }
10
11
12 public override Boolean initRecordProcessing(Object record, Object optionalOldRecord) {
13 // check if contact has new or changed value of AccountId if so add to finishSyncProcess method
14 Contact cnt = (Contact)record;
15 if (isNewOrChanged(cnt, (SObject)optionalOldRecord, Contact.AccountId) && cnt.AccountId != null) {
16 addToSyncFinish(record, optionalOldRecord);
17 accountIds.add(cnt.AccountId);
18 if (optionalOldRecord != null) {
19 accountIds.add(((Contact)optionalOldRecord).AccountId);
20 }
21 }
22 return false;
23 }
24
25
26 public override void finishSyncProcess(List<Object> records, List<Object> optionalOldRecords) {
27 // sets numberofemployees field for every account within the accountId set
28 // for every account without contacts set numberofemployees to zero
29 if (!accountIds.isEmpty()) {
30 for (AggregateResult result : [
31 SELECT AccountId, Count(Id) cnt
32 FROM Contact
33 WHERE AccountId IN :accountIds
34 GROUP BY AccountId]) {
35 getContext().addModificationToUpdate(
36 (Id)result.get('AccountId'),
37 Account.NumberOfEmployees,
38 Integer.valueOf((Decimal)result.get('cnt')));
39 accountIds.remove((Id)result.get('AccountId'));
40 }
41 for (Id accountId : accountIds) {
42 getContext().addModificationToUpdate(accountId, Account.NumberOfEmployees, 0);
43 }
44 }
45 }
46}
Again we are using addModificationToUpdate as it does not execute any DMLs and is safe for low level record logic. After adding a Contact to Account you can see the result.