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
Jessica CarstensJessica Carstens 

Use an Apex Trigger to add Primary Contact First Name and Email to Opportunity Page

I'm trying to send emails to clients that are triggered by changes to the Opportunity. I've created two new fields on the Opportunity to hold the client's name and email address.

I've writted a trigger which works great expcept when you go to convert a lead into a contact with a new Opportunity.

trigger UpdateClientEmail on Opportunity (after update) {
   for (Opportunity o : Trigger.new) {
if (o.StageName <> 'Closed/Lost') {

       OpportunityContactRole ContactRole =
            [SELECT ContactID from OpportunityContactRole where IsPrimary = True and OpportunityId = :o.id]; 
       Contact c =
            [SELECT FirstName, Email FROM Contact WHERE ID = :ContactRole.ContactID];
       o.Client_Name__c = c.FirstName;
       o.Client_Email__c = c.Email;
       }
     }
     }

When I go to convert a new lead I get this error:

Error: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateClientEmail: execution of AfterUpdate caused by: System.QueryException: List has no rows for assignment to SObject Trigger.UpdateClientEmail: line 5, column 1: [] Class.leadconvert.BulkLeadConvert.handleOpportunityInserts: line 730, column 1 Class.leadconvert.BulkLeadConvert.convertLead: line 104, column 1

I'm not sure how to change my trigger so that it only applies to opportunities that have already been created. I've got workflows that get the fields updated correctly when a lead is created and converted. The only time I need the trigger is when the Primary Contact is changed from one contact to another or when the email address for the contact is changed.

Any help is much appreciated.
Jessica CarstensJessica Carstens
I added in an if statement that the Amount was greater than 0 and that seems to have fixed the problem
 
trigger UpdateClientEmail on Opportunity (before update) {
   for (Opportunity o : Trigger.new) {
if (o.Amount > 0)  {

       OpportunityContactRole ContactRole =
            [SELECT ContactID from OpportunityContactRole where IsPrimary = True and OpportunityId = :o.id]; 
       Contact c =
            [SELECT FirstName, Email FROM Contact WHERE ID = :ContactRole.ContactID];
       o.Client_Name__c = c.FirstName;
       o.Client_Email__c = c.Email;
       }
     }
     }

The problem I'm having now is that my test class keeps failing. This is the error I'm getting:

"System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateClientEmail: execution of BeforeUpdate caused by: System.QueryException: List has no rows for assignment to SObject Trigger.UpdateClientEmail: line 5, column 1: []"

Here is my test class:
 
@istest
private class TestClassUpdateClientEmail2 {
    static testMethod void testUpdateField() {
    //Setup Account
    Account acc = new Account();
    acc.Name = 'Acme Account Test';
    acc.BillingCountry = 'US';
    acc.ShippingCountry = 'US';
    acc.BillingState = 'IL';
    acc.Website = 'www.acmeaccounttest.com';
    insert acc;
    
    //Setup Contact
    Contact con = new Contact();
    con.FirstName = 'Henry';
    con.LastName='Smith';        
    con.AccountId = acc.Id;
    con.LeadSource = 'test trigger';
    con.Email = 'HSmith@acme.com';
    con.Phone = '1234567890';
    insert con;
    
    //Setup Opportunity
    Opportunity opp = new Opportunity();
    opp.AccountId = acc.Id;
    opp.Name = 'test lead source trigger';
    opp.StageName = 'Working the Deal';
    opp.CloseDate = system.today();
    opp.How_You_Heard__c='Referral';
    opp.LeadSource='Email';
    opp.Purchase_Time_Frame__c='This Week';
    opp.Preferred_Delivery_Location__c='Sausalito Branch';
    opp.Client_Name__c='';
    opp.Client_Email__c='';
    opp.Amount=295.00;
    insert opp;
    
    //Setup Vehicle
    Vehicle__c veh = new Vehicle__c();
    veh.Year__c = '2016';
    veh.Make__c = 'Toyota';
    veh.Model__c = 'Corolla';
    veh.Stage__c = 'Pre-Search';
    veh.Exterior_Color__c = 'Blue';
    veh.Transmission__c = 'Automatic';
    insert veh;
    
    //setup Opportunity Contact Role
    OpportunityContactRole ocr = new OpportunityContactRole();
    ocr.ContactId = con.Id;
    ocr.IsPrimary = True;
    ocr.OpportunityId = opp.Id;
    ocr.Role = 'Client';
    insert ocr;
  
   Test.startTest();
        List<opportunity> newopp;
        System.assertEquals(con.Email, opp.Client_Email__c);
        System.assertEquals(con.FirstName, opp.Client_Name__c);
        Test.stopTest();
       
    }
  }

Any help is much appreciated. I'm still learning!

Thanks!
Alexander_EAlexander_E
It looks like you have an Custom Field made required on creation. This required field is not requested during lead conversion. That causes your error.

check your fields setup and validation rules for
Purchase_Time_Frame__c
Preferred_Delivery_Location__c
Client_Name__c
Client_Email__c