function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
ABC XYZ 39ABC XYZ 39 

After insert and After update triggers firing at the same time for a new record creation

Basic Logic is :
For insert trigger case --- processNewContact is the class. 
Whenever a new contact is created of the type 'customer', it is inserted into objQ object.
Now, when the contact is created, a custom field 'PID' needs to be updated from external system into Salesforce. 


After Update Trigger Case --->
Whenever an existing contact is updated - If any of the fields change with 'PID' value null, updated record needs to be pushed into objQ object. Then the external system will reply back with 'PID' value which will assigned to Salesforce record.

Behavior now :
Whenever a  new contact  is created, 2 copies of the same record are inserted into the Queue object. This I am assuming is happening because 'after insert' and 'after update' triggers aer firing for every new contact created. 


I don't understand why this is happening. There are no workflows impacting the behavior . It has to do with logic in the class below. UpdateContact  is similar to processNewContact method below ; only difference is checking whether any of the fields have changed. If they have and 'PID' value is null, record will be pushed into Queue object.  Please assist. I have been trying to fix for sometime without any luck...Thanks...




public static void processNewContact(Map<Id, Contact> newContactMap, Map<Id, Contact> oldContactMap)
02{
03    List<Queue__c> lstQ = new List<Queue__c>();   
04    Id idContactCustomerRecType;
05    Map<Id, String> mapIdToAccountName = new Map<Id, String>();
06     
07    // Assuming Contact type Name is 'Customer'
08    List<RecordType> lstRecType = new List<RecordType>([SELECT Id FROM RecordType WHERE Name = 'Customer' AND SobjectType = 'Contact']);
09    if(!lstRecType.isEmpty())
10        idContactCustomerRecType = lstRecType[0].Id;
11         
12    if(idContactCustomerRecType != null)
13    {
14        // we can;t fetch parent fields directly, so collect account Ids first
15        for(Contact objContact : newContactMap.values())
16        {
17            if(objContact.AccountId != null)
18                mapIdToAccountName.put(objContact.AccountId, null);
19        }
20    }
21     
22    // iterate over account with matching collected Ids and fetch names
23    for(Account objAccount : [SELECT Id, Name FROM Account WHERE Id IN : mapIdToAccountName.keySet()])
24    {
25        mapIdToAccountName.get(objAccount.Id, objAccount.Name);
26    }
27     
28    // loop again to perform business logic
29    for(Contact objContact : newContactMap.values())
30    {
31        /* 1. If Contact RecordType is Customer AND if LastName != Account.Name, insert Queue **/
32        if(objContact.RecordTypeId == idContactCustomerRecType && objContact.AccountId != null && objContact.LastName != mapIdToAccountName.get(objContact.AccountId))
33        {
34            Queue__c objQ = new Queue__c();
35            objQ.Object_Name__c='Contact';
36            objQ.Description__c= 'New Contact';
37            objQ.Record_Id__c = objContact.Id;
38            objQ.Notification_Timestamp__c= objContact.CreatedDate;
39            lstQ.add(objQ);
40        }
41             
42    }
43     
               isCreated = true;

44    if(!lstQ.isEmpty())
45        insert lstQ;
46     


Trigger Invocation :  After UPDATE
if(ContactController.isCreated==false ){
        ContactController.UpdateContact(Trigger.newMap, Trigger.oldMap);
    } 

AFTER INSERT 
    ContactController.processNewContact(Trigger.newMap, Trigger.oldMap);

47}