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
FranchisingGuruFranchisingGuru 

HELP: Update Multiple ContactRoles from Opportunity Trigger

I am a complete newbie to Apex triggers, but have semi-successfully completed a trigger that will initiate from an opportunity.  The trigger is supposed to retrieve the associated contact Ids by retrieving them from the OpportunityContactRole.  Once the contact(s) have been identified, I want to send an email to the contact and update a field within the contact. 

 

I have three main concerns/problems:

  1. If there is more than one contact associated to an opportunity, only one contact is updated and sent an email
  2. Is there a way to limit emails to send only once, rather than every time an opportunity is edited and meets the criteria? Or will I have to upsert an opportunity field (i.e. - a checkbox indicating email sent) and make sure that if that field is checked, the trigger does not fire?
  3. Is this trigger "bulkified"?

I have copied the applicable code for my trigger in progress below.  Again, my main issue is when there is more than one contact associated to an opportunity:

 

trigger portalEmailSend on Opportunity (after update) {
for(Opportunity oppEmail : Trigger.new) {
        if(oppEmail.StageName == 'Qualified' && oppEmail.Account_Name_Copy__c == 'Something'  && oppEmail.Send_Auto_Discovery_Portal_Emails__c==True) {       
            List<OpportunityContactRole> theOppConRole = [SELECT Id, OpportunityId,
ContactId FROM OpportunityContactRole WHERE OpportunityId=:oppEmail.ID];
//get OpportunityContactRole ID from Opportunity that initiated trigger
            for (OpportunityContactRole contactRole:theOppConRole) {
// add OpportunityContactRole to the main OpportunityContactRole list
theOppConRole.add(contactRole);
                     
                 if(contactRole.ContactId==NULL){

                 }    
                 else{       
                 //Sending email to matching contact(s)
                 Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                 mail.settargetObjectId(contactRole.ContactId);
                 mail.settemplateId('IdofTemplate');
                 mail.setsaveAsActivity(true);
                 mail.setsenderDisplayName(oppEmail.Owner.Name);
                 mail.setreplyTo(oppEmail.Owner.Email);
                 Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
                
            
                //updating opportunity stage field in matching contact record(s)
                List<Contact> inQuestion = [SELECT Id, FirstName, LastName,
Opportunity_Stage__c FROM Contact WHERE Id=:contactRole.ContactId];
                    for (Contact contactMatch:inQuestion) {
                    
                    contactMatch.Opportunity_Stage__c = 'Qualified';
                    inQuestion.add(contactMatch);
                    upsert contactMatch;
                    break; //exit after upsert to avoid continuous looping
                    }
                    break; //break initial for loop that processes contact data
              }
            }
        }
jkucerajkucera

Directly responding to your question, the 1 email may resulting from governor limits on sendEmail method:

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm?SearchType=Stem&Highlight=governor|Governors|Governor|governors||limitations|limits|Limitations|limited|Limits|limit|LIMIT|Limit|limiting|LIMITS|limitation

 

A few other notes on your trigger- the queries in a loop means this breaks any time you have more then 20 oppty's updated at once.  You should change it to query for all contact roles at once (1 query) and then loop through the list.  Check out this article for more details:

http://wiki.developerforce.com/index.php/Best_Practice:_Bulkify_Your_Code