You need to sign in to do that
Don't have an account?
ABC XYZ 39
After insert and After update triggers firing at the same time for a new record creation - Reposting
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...I need to fix it as soon as possible. I had posted the same earlier but didn't get any reply. I am new to programming and can't figure out how to fix it. 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
47 }
Trigger Invocation : After UPDATE
if(ContactController.isCreated==false ){
ContactController.UpdateContact(Trigger.newMap, Trigger.oldMap);
}
AFTER INSERT
ContactController.processNewContact(Trigger.newMap, Trigger.oldMap);
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...I need to fix it as soon as possible. I had posted the same earlier but didn't get any reply. I am new to programming and can't figure out how to fix it. 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
47 }
Trigger Invocation : After UPDATE
if(ContactController.isCreated==false ){
ContactController.UpdateContact(Trigger.newMap, Trigger.oldMap);
}
AFTER INSERT
ContactController.processNewContact(Trigger.newMap, Trigger.oldMap);
For Trigger Invocation you can do like this :
// after update
if(Trigger.isUpdate && Trigger.isAfter){
ContactController.UpdateContact(Trigger.newMap, Trigger.oldMap);
}
// after insert
else if(Trigger.isInsert && Trigger.isAfter){
ContactController.processNewContact(Trigger.newMap, Trigger.oldMap);
}
Please retry and let us know the results. Good Luck!
Below is the code for updatecontact. If few of the fields are getting modified, then we push into the queue. (OR)
If during the update, if P id is found to be still missing, records will be pushed into the queue object if there are any updates to the record.
public static void UpdateContact(Map<Id, Contact> newContactMap, Map<Id, Contact> oldContactMap) {
List<Queue__c> lstQ = new List<Queue__c>();
Id idContactCustomerRecType;
Map<Id, String> mapIdToAccountName = new Map<Id, String>();
List<RecordType> lstRecType = new List<RecordType>([SELECT Id FROM RecordType WHERE Name = 'Customer' AND SobjectType = 'Contact']);
//Considering only 'Customer' type of contact records
if(!lstRecType.isEmpty())
idContactCustomerRecType = lstRecType[0].Id;
if(idContactCustomerRecType != null)
{
// Can't fetch parent fields directly, so collecting account Ids first
for(Contact objContact : newContactMap.values())
{
if(objContact.AccountId != null)
mapIdToAccountName.put(objContact.AccountId, null);
}
}
// iterate over account with matching collected Ids and fetch names
for(Account objAccount : [SELECT Id, Name FROM Account WHERE Id IN : mapIdToAccountName.keySet()])
{
mapIdToAccountName.put(objAccount.Id, objAccount.Name);
}
for(Contact objContact: newContactMap.values()) {
//Checking only for changes in field values
if(objContact.RecordTypeId == idContactCustomerRecType && objContact.AccountId != null && objContact.LastName != mapIdToAccountName.get(objContact.AccountId)) {
if( (objContact.A__c!= oldContactMap.get(objContact.Id).A__c) || (objContact.B__c!= oldContactMap.get(objContact.Id).B__c) ||
(objContact.D__c!= oldContactMap.get(objContact.Id).D__c)
{
//Adding all contact records with changed values to Queue object
Queue__c objQ = new Queue__c()
objQ.Object_Name__c='Contact';
objQ.Description__c=' Updated Contact';
objQ.Record_Id__c = objContact.Id;
objQ.Notification_Timestamp__c= objContact.LastModifiedDate;
lstQ.add(objQ);
}
//Considering all contact records with null values for MDM Person Ids
else if (objContact.PID__c==null)
{
Queue__c objQ = new Queue__c()
objQ.Object_Name__c='Contact';
objQ.Description__c= 'PID Missing';
objQ.Record_Id__c = objContact.Id;
objQ.Notification_Timestamp__c= objContact.LastModifiedDate;
lstQ.add(objQ);
}
}
}
isCreated = true;
if(!lstQ.isEmpty()) insert lstQ;
}
Can you pls explain in brief what you have changed in the code above? Thanks for all your help
Nayana, sorry, additonal logic which I forgot to include before is for update case should trigger only if specific users modify the record.
Logic is :
if(label.Unauthorized_User!=l.lastmodifiedbyid){
{ Resot of Update Logic }
}
Will above code have to be changed Nayana? Please let me know...Also, what would the test class for above piece of code look like? Thanks
Have you checked process builder?
Please post whole trigger code and controller code ( just to make sure everything is proper).
Here is the code:
// Controller Class with processContact method
public class ContactController {
public void processContact(Map<Id, Contact> newContactMap, Map<Id, Contact> oldContactMap)
{
List<Queue__c> lstQ = new List<Queue__c>();
Id idContactCustomerRecType;
Map<Id, String> mapIdToAccountName = new Map<Id, String>();
List<RecordType> lstRecType = new List<RecordType>([SELECT Id FROM RecordType WHERE Name = 'Customer' AND SobjectType = 'Contact']);
if(!lstRecType.isEmpty())
idContactCustomerRecType = lstRecType[0].Id;
if(idContactCustomerRecType != null)
{
// we can't fetch parent fields directly, so collecting account Ids first
for(Contact objContact : newContactMap.values())
{
if(objContact.AccountId != null)
mapIdToAccountName.put(objContact.AccountId, null);
}
}
// iterate over account with matching collected Ids and fetch names
for(Account objAccount : [SELECT Id, Name FROM Account WHERE Id IN : mapIdToAccountName.keySet()])
{
mapIdToAccountName.put(objAccount.Id, objAccount.Name);
}
// loop again to perform business logic
for(Contact objContact : newContactMap.values())
{
/* 1. If Contact RecordType is Customer AND if LastName != Account.Name, insert Queue **/
if( objContact.RecordTypeId == idContactCustomerRecType
&& objContact.AccountId != null && objContact.LastName != mapIdToAccountName.get(objContact.AccountId)
{
if(Trigger.isUpdate)
{
if(label.Unauthorized_User!=objContact.lastmodifiedbyid)
{
if(objContact.A__c!= oldContactMap.get(objContact.Id).A__c
|| objContact.B__c!= oldContactMap.get(objContact.Id).B__c
|| objContact.D__c!= oldContactMap.get(objContact.Id).D__c)
{
objQ.Description__c= 'Updated Contact';
objQ.Record_Id__c = objContact.Id;
objQ.Notification_Timestamp__c= objContact.CreatedDate;
lstQ.add(objQ);
}
else if(objContact.PID__c == null)
{
objQ.Description__c= 'PID Missing';
objQ.Record_Id__c = objContact.Id;
objQ.Notification_Timestamp__c= objContact.CreatedDate;
lstQ.add(objQ);
}
}
}
if(Trigger.isInsert)
{
objQ.Description__c= 'New Contact';
objQ.Record_Id__c = objContact.Id;
objQ.Notification_Timestamp__c= objContact.CreatedDate;
lstQ.add(objQ);
}
}
}
if(!lstQ.isEmpty())
insert lstQ;
}
}
Trigger Invocation :
Contact - After Insert
if(Trigger.isInsert && Trigger.isAfter){
ContactController.processContact(Trigger.newMap, Trigger.oldMap);
}
Contact - After Update
if(Trigger.isUpdate && Trigger.isAfter){
ContactController.processContact(Trigger.newMap, Trigger.oldMap);
}