+ Start a Discussion
ColaCola 

Trigger on Contact to updated related Opportunity

Hi, 

I'm trying to create a trigger that updates a contact's related opportunity location fields (City, State/Province, Country) based on the contact's location fields. This should only udpate the opportunity's location fields when the fields are previously blank. The code I have so far is below, but it doesn't seem to be working. 

trigger updateOppLocation on Contact (after insert) {
    
    List<OpportunityContactRole> contactRoles = [SELECT OpportunityId,ContactId
                                                 FROM OpportunityContactRole
                                                 WHERE ContactId IN : Trigger.new];
    
    if(contactRoles.size()>0) {
        Map<Id,Id> conOpp_map = new Map<Id,Id>();
        
        for(OpportunityContactRole cr : contactRoles) {
            conOpp_map.put(cr.ContactId,cr.OpportunityId);
        }
        
        List<Opportunity> opp_list = new List<Opportunity>([SELECT Id 
                                                       FROM Opportunity
                                                       WHERE Id IN : conOpp_map.values()]);
        
        for(Contact c : Trigger.new) {
            if(conOpp_map.containsKey(c.Id)) {
                for (Opportunity o : opp_list) {
                    if (o.City__c == null && o.State_Province__c == null && o.Country__c == null) {
                    	o.City__c = c.MailingCity;
                    	o.State_Province__c = c.MailingState;
                        o.Country__c = c.MailingCountry; 
                    }
                }
            }
        } 
   	update opp_list;
    } 
}

Any advice on how to get this to work is appreciated. 
Vatsal KothariVatsal Kothari
Hi Cola,

You can try below code:
trigger updateOppLocation on Contact (after insert) {
    
	Set<Id> contactIds = new Set<Id>();
	Map<Id,Id> conOpp_map = new Map<Id,Id>();
	Map<Id,Opportunity> oppMap = new Map<Id,Opportunity>();
	
	for(Contact con : trigger.new){
		if(con.Id != null){
			contactIds.add(con.Id);
		}
	}
	
	for(OpportunityContactRole cr : [SELECT OpportunityId,ContactId FROM OpportunityContactRole WHERE ContactId IN : contactIds]) {
		if(cr.ContactId != null){
            conOpp_map.put(cr.ContactId,cr.OpportunityId);
		}
    }
	
	for(Opportunity opp : [SELECT Id,City__c,State_Province__c,Country__c FROM Opportunity WHERE Id IN : conOpp_map.values()]){
		oppMap.put(opp.Id,opp);
	}
	
	for(Contact c : Trigger.new){
		if(conOpp_map.containsKey(c.Id)) {
			if(oppMap.get(conOpp_map.get(c.Id)).City__c == null && oppMap.get(conOpp_map.get(c.Id)).State_Province__c == null && oppMap.get(conOpp_map.get(c.Id)).Country__c == null){
				oppMap.get(conOpp_map.get(c.Id)).City__c = c.MailingCity;
				oppMap.get(conOpp_map.get(c.Id)).State_Province__c = c.MailingState;
				oppMap.get(conOpp_map.get(c.Id)).Country__c = c.MailingCountry; 
			}
		}
	}
	
	if(!oppMap.isEmpty()){
		update oppMap.values();
	}	
}
If this solves your problem, kindly mark it as the best answer.

Thanks,
Vatsal
ColaCola
Hi Vatsal,

It seems to work very well except for one issue. When the trigger is on, the related Account location (City, State, Country) is getting overridden whenever a new lead is converted. Do you know how I could stop this from happening? 

Cheers
Vatsal KothariVatsal Kothari
Hi Cola,

What you can do for this is to bypass the trigger if contact is created through Lead conversion.

For this can refer below link:

https://success.salesforce.com/answers?id=90630000000hXN2AAM

Follow the process explained in above link and do below modification in your code in 8th line.

if(con.Id != null && con.Created_From_Lead__c == false)
If this solves your problem, kindly mark it as the best answer.

Thanks,
Vatsal
ColaCola
Sorry maybe I wasn't clear. I want to update the contact when it is created through a Lead conversion. However, I just don't want the account fields to be updated. Is there a way around this?