Hey guys, today in this post we are going to learn about Apex trigger on Account to create and count the number of Contact records associated with Account object based on custom field when Account record is created/updated in Salesforce.
Real time scenarios:- Write a trigger on Account object where create a custom field as Employee (Number type).
If user insert the parent record, the child record should be automatic inserted equal to the same value of employee.
Or if user update the value of employee less then the total number of child records, in this case the child records should be exist only equal to value of employee size, rest records of child object should be automatic removed.
Files we used in this post example
EmployeeSizeTrigger2.apxt | Apex Class Trigger | It will be fired whenever insert or update a record on parent object |
Parent Cusotm Object:- Account Custom Field:- Employee Size (Employee__c) |
Parent Object with Custom Field | Trigger on Account object and update the count of related child records with the custom field value of Account object. |
Child Custom Object:- Contact Custom Field:- AccountId : Lookup(Account) |
Child Object with Lookup Field |
Live Example
You can download file directly from github by Click Here.
Other related post that would you like to learn in Salesforce
- Find the below steps ▾
Create Apex Trigger
Step 1:- Create Apex Trigger : employeeSizeTrigger2.apxt
From Developer Console >> File >> New >> Apex Trigger
employeeSizeTrigger2.apxt [Apex Class Controller]
TRIGGER employeeSizeTrigger2 ON Account (BEFORE INSERT, BEFORE UPDATE, after INSERT, after UPDATE, BEFORE DELETE, after DELETE) {
Map<Id, List<Contact>> prntMap = NEW Map<Id, List<Contact>>();
Map<Id, Account> prntOldMap = NEW Map<Id, Account>();
Map<Id, Integer> prntMapChildNo = NEW Map<Id, Integer>();
Map<Id, Decimal> empValMap = NEW Map<Id, Decimal>();
Set<Id> parentKey = prntMap.keySet();
List<List<Contact>> childKeyVal = NEW List<List<Contact>>();
List<Account> oldVal = NEW List<Account>();
Set<Id> prntSetId = NEW Set<Id>();
List<Contact> childObjList = NEW List<Contact>();
List<Contact> childObjNull = NEW List<Contact>();
Set<Id> childNullSetId = NEW Set<Id>();
DECIMAL childSize;
DECIMAL empVal;
DECIMAL empValOld;
IF(TRIGGER.isBefore){
system.debug('Event before trigger');
}ELSE IF(TRIGGER.isAfter){
system.debug('Event after trigger');
oldVal = TRIGGER.old;
FOR(Account par: [SELECT Id, Name, Phone, Employee__c, (SELECT Id, Name, FirstName, LastName, AccountId FROM Contacts) FROM Account WHERE Id IN: TRIGGER.newMap.values()]){
system.debug('par$$$$$$ ' + par);
prntMap.put(par.Id, par.Contacts);
prntMapChildNo.put(par.Id, (par.Contacts).size());
}
system.debug('empValOld# ' +empValOld);
FOR(List<Contact> childObjVal:prntMap.values()){
system.debug('childObj!!!! ' + childObjVal);
childKeyVal.add(childObjVal);
}
system.debug('childKeyVal## ' + childKeyVal);
List<Account> prntList = [SELECT Id, Name FROM Account WHERE Id IN:prntMap.keySet()];
FOR(Account pr1:prntList){
prntSetId.add(pr1.Id);
}
system.debug('prntSetId ' + prntSetId);
FOR(Account prantEmp:[SELECT Id,Employee__c FROM Account WHERE Id IN:prntMap.keySet()]){
empValMap.put(prantEmp.Id, prantEmp.Employee__c);
empVal = prantEmp.Employee__c;
system.debug('empValMap ' + empValMap);
}
system.debug('empValMap ' + empValMap);
system.debug('empVal ' + empVal);
List<Contact> childObjKey = NEW List<Contact>();
FOR(Contact childKey: [SELECT Id, Name, AccountId FROM Contact WHERE AccountId=:prntSetId]){
system.debug('childKey####$ ' + childKey);
childObjKey.add(childKey);
}
IF(TRIGGER.isInsert){
FOR(INTEGER i=0; i<empVal; i++){
FOR(Account prntSet:[SELECT Id, Name FROM Account WHERE Id IN:prntSetId]){
Contact childObj = NEW Contact();
childObj.LastName='childMap ' + i;
childObj.AccountId=prntSet.id;
childObjList.add(childObj);
}
}
system.debug('childObjList ' + childObjList);
INSERT childObjList;
}ELSE IF(TRIGGER.isUpdate){
FOR(Account parOld: oldVal){
empValOld = parOld.Employee__c;
}
IF(empVal !=empValOld){
FOR(INTEGER intNo:prntMapChildNo.values()){
system.debug('intNo@@ ' + intNo );
childSize = intNo;
}
system.debug('childSize ' + childSize);
IF(empVal > childSize){
empVal = empVal - childSize;
FOR(INTEGER i=0; i<empVal; i++){
FOR(Account prntSet1:[SELECT Id, Name FROM Account WHERE Id IN:prntSetId]){
Contact childObj2 = NEW Contact();
childObj2.LastName='update child ' + i;
childObj2.AccountId=prntSet1.Id;
childObjKey.add(childObj2);
}
}
upsert childObjKey;
}ELSE{
empVal = childSize - empVal;
system.debug('empVal $$$ ' + empVal );
FOR(INTEGER i=0; i<empVal; i++){
childObjKey[i].AccountId=NULL;
childObjNull.add(childObjKey[i]);
}
UPDATE childObjNull;
FOR(Contact childSet:childObjNull){
childNullSetId.add(childSet.Id);
}
system.debug('childNullSetId## ' + childNullSetId);
List<Contact> deleteNull = [SELECT Id FROM Contact WHERE ID IN:childNullSetId];
DELETE deleteNull;
}
}
}
}
}
Further post that would you like to learn in Salesforce
How many records can trigger handle?
When more than 200 records need to be triggered, Salesforce runs the trigger in chunks of 200. So, if 1000 records are updating, Salesforce runs the trigger 5 times on 200 records each time
Can we have roll up summary fields in case of parent/child relationship?
Yes, we can create Roll up Summary field on parent object only with master detail relation between objects.
How many records will execute in trigger in one execution?
Triggers execute on batches of 200 records at a time. So if 400 records cause a trigger to fire, the trigger fires twice, once for each 200 records. For this reason, you don't get the benefit of SOQL for loop record batching in triggers, because triggers batch up records as well.
Related Topics | You May Also Like
Our Free Courses →
👉 Get Free Course →
📌 Salesforce Administrators 📌 Salesforce Lightning Flow Builder 📌 Salesforce Record Trigger Flow Builder |
👉 Get Free Course →
📌 Aura Lightning Framework 📌 Lightning Web Component (LWC) 📌 Rest APIs Integration |