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
huskerwendyhuskerwendy 

Trigger to check if Primary Contact changes on opportunity

I found this app on the appexchange that will validate if there is a primary contact on the opportunity. However, I also need to know if the primary contact has changed. This is a link to the app:
https://appexchange.salesforce.com/listingDetail?listingId=a0N300000025Vs1EAE

I'm trying to modify the code but am getting an error.
trigger updatecontactrolecount on Opportunity (before insert, before update){
Boolean isPrimary;
Integer iCount;
Boolean isPrimaryChanged;

Map<String, Opportunity> oppty_con = new Map<String, Opportunity>();//check if the contact role is needed and add it to the oppty_con map
for (Integer i = 0; i < Trigger.new.size(); i++) 
{
        oppty_con.put(Trigger.new[i].id,
        Trigger.new[i]);      
}
    
isPrimary = False; 
isPrimaryChanged = False;
for (list<OpportunityContactRole> oppcntctrle :[select OpportunityId, ContactID from OpportunityContactRole where (OpportunityContactRole.IsPrimary = True and OpportunityContactRole.OpportunityId in :oppty_con.keySet())]){
    if (oppcntctrle .Size() >0) {
         isPrimary = True; 
        //for (Opportunity o : trigger.new){
            //OpportunityContactRole contactRole =[select ContactID from OpportunityContactRole where IsPrimary = true and OpportunityId = :oppcntctrle.id];   
            for (list<OpportunityContactRole> oldContactRole :[select OpportunityID, ContactID from OpportunityContactRole where OpportunityContactRole.IsPrimary = True and OpportunityId IN :Trigger.oldMap.keySet()]){               
                if(oldContactRole.ID != oppcntctrle.ContactID){      
                    isPrimaryChanged = true;
                }           
               }    
        //}
    }     
}

iCount = 0;
for (List<OpportunityContactRole> oppcntctrle2 : [select OpportunityId from OpportunityContactRole where (OpportunityContactRole.OpportunityId in :oppty_con.keySet())])//Query for Contact Roles
{    
 if (oppcntctrle2 .Size()>0)
 {
 iCount= oppcntctrle2 .Size();     
 }
}
for (Opportunity Oppty : system.trigger.new) //Check if  roles exist in the map or contact role isn't required 
{
Oppty.Number_of_Contacts_Roles_Assigned__c = iCount;
Oppty.Primary_Contact_Assigned__c =isPrimary; 
Oppty.Primary_Contact_Changed__c= isPrimaryChanged;
}
}
I'm getting an error (Initial term of field expression must be a concrete SObject: List) on line 21  if(oldContactRole.ID != oppcntctrle.ContactID){  

What am I doing wrong?  
 
James LoghryJames Loghry
In line 20 in your example, change "List<OpportunityContactRole>" to "OpportunityContactRole".
huskerwendyhuskerwendy
Hi Amit, Thanks for your help but now I'm getting an unexpectedf otken at line 30. It looks like the brackets are okay so I'm not sure what is causing it.
 
Amit Chaudhary 8Amit Chaudhary 8
NOTE:- I am not aware about requirement. I just fixed your syntex issue
Please try below code.
trigger updatecontactrolecount on Opportunity (before insert, before update)
{
	Boolean isPrimary;
	Integer iCount;
	Boolean isPrimaryChanged;

	Map<String, Opportunity> oppty_con = new Map<String, Opportunity>();//check if the contact role is needed and add it to the oppty_con map
	for (Integer i = 0; i < Trigger.new.size(); i++) 
	{
			oppty_con.put(Trigger.new[i].id,Trigger.new[i]);      
	}
    
	isPrimary = False; 
	isPrimaryChanged = False;
	for (OpportunityContactRole oppcntctrle :[select OpportunityId, ContactID from OpportunityContactRole where (OpportunityContactRole.IsPrimary = True and OpportunityContactRole.OpportunityId in :oppty_con.keySet())] )
	{
		isPrimary = True;
		for (list<OpportunityContactRole> oldContactRole :[select OpportunityID, ContactID from OpportunityContactRole where OpportunityContactRole.IsPrimary = True and OpportunityId IN :Trigger.oldMap.keySet()])
		{               
			if(oldContactRole.ID != oppcntctrle.ContactID)
			{      
				isPrimaryChanged = true;
			}           
		}    
    }  

	iCount = 0;
	for( OpportunityContactRole oppcntctrle2 : [select OpportunityId from OpportunityContactRole where (OpportunityContactRole.OpportunityId in :oppty_con.keySet() ) ] )
	{    
			iCount++;
	}
	for (Opportunity Oppty : system.trigger.new) //Check if  roles exist in the map or contact role isn't required 
	{
		Oppty.Number_of_Contacts_Roles_Assigned__c = iCount;
		Oppty.Primary_Contact_Assigned__c =isPrimary; 
		Oppty.Primary_Contact_Changed__c= isPrimaryChanged;
	}
}

 
huskerwendyhuskerwendy
I'm still getting the error, "Initial term of field expression must be a concrete SObject: List<OpportunityContactRole>" on line 20 "If(oldcontactRole.ID != oppcntctrle.ContactID)"

 
James LoghryJames Loghry
@Amit, please stop confusing Wendy and giving her bad information.  It's apparent you haven't even attempted to see if your "fix" for her worked in the first place.  

@Wendy, as I mentioned earlier, change List<OpportunityContactRole> to OpportunityContactRole and save your file.  You may or may not get additional errors, but that will fix the one on line 20.
huskerwendyhuskerwendy
Hi James, Thanks for the help. I put my code back and modified that line but I'm still getting the same error on line 20. Is there a different way that I should be comparing the old contact ID to the new contact id for the contact that is marked as primary?
huskerwendyhuskerwendy
I fixed it so there aren't any errors. However, it's not updating the "Primary_Contact_Changed__c" if the contact role "Is Primary" field is changed. I don't think I am actually accessing the Contact ID for the contact role but I don't know how to. Here's the updated code: 
trigger updatecontactrolecount on Opportunity (before insert, before update){

Boolean isPrimary;
Integer iCount;
Boolean isPrimaryChanged;

Map<String, Opportunity> oppty_con = new Map<String, Opportunity>();//check if the contact role is needed and add it to the oppty_con map
for (Integer i = 0; i < Trigger.new.size(); i++) {
        oppty_con.put(Trigger.new[i].id,
        Trigger.new[i]);      
}

isPrimary = False; 
isPrimaryChanged = False;    
for (list<OpportunityContactRole> oppcntctrle :[select OpportunityID, ContactID from OpportunityContactRole where (OpportunityContactRole.IsPrimary = True and OpportunityContactRole.OpportunityId in :oppty_con.keySet())]){
	if (oppcntctrle.Size() >0){
		isPrimary = True;     
	}
    for (OpportunityContactRole o: oppcntctrle){
        if (Trigger.isUpdate && (Trigger.oldMap.get(o.Id) <> Trigger.newMap.get(o.Id))){
            isPrimaryChanged = True;
        }
    }
}
    
iCount = 0;
for (List<OpportunityContactRole> oppcntctrle2 : [select OpportunityId from OpportunityContactRole where (OpportunityContactRole.OpportunityId in :oppty_con.keySet())])//Query for Contact Roles
{    
 if (oppcntctrle2 .Size()>0)
 {
 iCount= oppcntctrle2 .Size();     
 }
}
for (Opportunity Oppty : system.trigger.new) //Check if  roles exist in the map or contact role isn't required 
{
Oppty.Number_of_Contacts_Roles_Assigned__c = iCount;
Oppty.Primary_Contact_Assigned__c =isPrimary; 
Oppty.Primary_Contact_Changed__c = isPrimaryChanged;
}
}