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
CushtyCushty 

Upon Won Opportunity update contact fields (contact role)

Hi,

I am trying to write an apex trigger to update contact fields from a won opportunity (opportunity contact role) and have little knowledge of how to do so (admin background).

All products sit under a main 'product category'.  I have also added these categories as individual check boxes on the contact page.  
What I am trying to do is once the opportuntiy is closed Won, look at the opportunity products purchased and for each category they sit under, update the Contact Roles (Contact) record, setting each category checkbox to true.  Obviously there maybe more than once product bought from the same category so the checkbox only needs checking once

Here is what I attempted so far.  I created a rollup summary field (example Product category1) on the Opportunity object which counts how many products there are of Product category1.  Then the below trigger to fires after the Opportunity is closed won, checks there is more than 0 of Product category1 and updates the correctonding contact role (contact) checkbox.

trigger UpdateContactProduct on Opportunity (after update) {

        OpportunityContactRole ocr;
        Contact contact;
        Opportunity opp = Trigger.new[0];
        list<Contact> listToUpdate = new list<Contact>();
        if(opp.StageName == 'Won' && opp.Count_1Edit__c > 0){

          for(OpportunityContactRole iterating_oppConRole : [SELECT o.Role, 
                                                                      o.OpportunityId, 
                                                                      o.IsPrimary, 
                                                                      o.Id, 
                                                                      o.ContactId,
                                                                      o.Contact.Lead_Lifecycle_Stage__c 
                                                              FROM OpportunityContactRole o where o.OpportunityId =: opp.id])
                                                              {
               Contact tempContact = new Contact(id=iterating_oppConRole.ContactId, 
                X1Edit_bought__c = true);
                listToUpdate.add(tempContact);
               
           }
        }
        if(!listToUpdate.isEmpty())
            update listToUpdate;
}

This seems I am going the wrong way about it as I would have to create a roll summary field for each category and triggers for each when I am hoping it can be done in one trigger checking the products in th eopportunity and updating the categories on the contact record.

Thanks for any help that comes my way..
rajat Maheshwari 6rajat Maheshwari 6


Cushty, Please follow thye below code snippet and let me know If it works or not as per your requirement.


trigger UpdateContactProduct on Opportunity (after update) {

   Set<Id> st_OppId = new Set<Id>();
List<Contact> con_List;

for(Opportunity opp :Trigger.new)
  {
     if(opp.StageName=='Closed Won' && opp.Count_1Edit__c >0)
         st_OppId.add(opp.id);
 }

if(st_OppId!=null && !st_OppId.isEmpty())
    {

         for(OpportunityContactRole iterating_oppConRole : [SELECT Role, 
                                                                      OpportunityId, 
                                                                      IsPrimary, 
                                                                      Id, 
                                                                      ContactId,
                                                                      Contact.Lead_Lifecycle_Stage__c ,    Contact.X1Edit_bought__c 
                                                              FROM OpportunityContactRole  where OpportunityId IN : st_OppId])
                               {
                                      iterating_oppConRole.Contact.X1Edit_bought__c  = true;

                                       if(con_List == null)
                                           con_List = new List<Contact>();

                                          con_List.add(iterating_oppConRole.Contact);
                                }

               
           }
        
        if(con_List!=null && !con_List.isEmpty())
            update listToUpdate;
}

 
rajat Maheshwari 6rajat Maheshwari 6

Here replace "update listToUpdate" by "con_List"

Thanks

CushtyCushty
Hi,

I am not sure this works, as I may not not been clear.

Each product in salesforce sits under a product family for example 'Project Management', 'Software', 'Hardware' and I also have on the contact page a check box for each of these product families.

When I create an opportunity, select products and then set the opportunity to Won I want the corresponding contact (contact role in the opp) to have the checkboxes checked for each product family bought.  I think the above which I got to work was just checking the product family called 'X1Edit_bought__c'.

I achieved this by creating a rollup summarry to count the number of products on the Opportunity which fit this family (Count_1Edit__c) and then the trigger criteria runs if the Opp is won and the Count_1Edit__c  is greater than 0.  This means I would have to do a roll up summary field for each product family then a trigger for each one? or is there a way I can write a trigger to go through all the products on the opportunity, count what product families are there and check the box in the corresponding contact?  Is this some sort of If statement in the trigger or some way to do this?

Thanks for your help
 
rajat Maheshwari 6rajat Maheshwari 6

Hi Cushty,

Below must be procedure, as per my knowledge : - 

1. Rollup summary field created on opportunity to track the count for each fiiting family.

2. whenever opportunity will update with count fields due to action of rollup summary field ,then Trigger will fire to gather the contacts corresponding to attached contact role with check the count and update the checbox to true.

Suppose contact have two checkbox fields : -  FamilyA for "A" family and FamilyB for "B" Family.

Opportunity have two fields count_A_Family_Products and Count_B_Family_Products

 

Below is code snippet : - 

trigger UpdateContactProduct on Opportunity (after update) {

   Set<Id> st_OppId = new Set<Id>();
List<Contact> con_List;

for(Opportunity opp :Trigger.new)
  {
     if(opp.StageName=='Closed Won' )
         st_OppId.add(opp.id);
 }

if(st_OppId!=null && !st_OppId.isEmpty())
    {

         for(OpportunityContactRole iterating_oppConRole : [SELECT Role, 
                                                                      OpportunityId, 
                                                                      IsPrimary, 
                                                                      Id, 
                                                                      ContactId,
                                                                      Contact.Lead_Lifecycle_Stage__c ,    Contact.FamilyA__c, Contact.FamilyB__c, Opportunity.count_A_Family_Products__c,Opportunity.Count_B_Family_Products__c
                                                              FROM OpportunityContactRole  where OpportunityId IN : st_OppId])
                               {

                    if(iterating_oppConRole.Opportunity.count_A_Family_Products__c > 0)
                        {
                              iterating_oppConRole.Contact.FamilyA__c= true;
                        }
                    
                     if(iterating_oppConRole.Opportunity.count_B_Family_Products__c > 0)
                         {
                               iterating_oppConRole.Contact.FamilyB__c= true;
                         }

                     

                                       if(con_List == null)
                                           con_List = new List<Contact>();

                                          con_List.add(iterating_oppConRole.Contact);
                                }

               
           }
        
        if(con_List!=null && !con_List.isEmpty())
            update listToUpdate;
}


Thanks

 

CushtyCushty

Thanks 

this worked well.
I am just at 60% for the test class.....nearly there

Test class so far I have inserted account, contact, opportunity, contact role, product, price book, opportunity line item.....

CushtyCushty
Hi,
How do I create a test method for this?

I tried and got 60% and now I get an error saying 'Methods defined as TestMethod do not support Web service callouts'

here is what I had and not sure if its a bit long winded; -

@IsTest

Public Class testAddProductsBought
 {
    static testMethod void ValidateContactProduct()
    {
    
    Account a = new Account();
    a.Name ='demo';
    a.Industry = 'Education';
    a.BillingCountry = 'United Kingdom';
    insert a;
    
    
    Contact c = new Contact();
    c.FirstName = 'Lord';
    c.LastName = 'Test2';
    c.Accountid = a.id; 
    c.RecordTypeid = '012w000000063q6AAA';
    c.MailingStreet = '2 Ringo Starr Road';
    c.MailingCity = 'BedRock';
    c.MailingPostalCode = 'AL9 3RD';
    insert c;
    
    
    Contact ci = new Contact();
    ci.FirstName = 'Bob';
    ci.LastName  = 'Test';
    ci.AccountId = a.id;
    ci.RecordTypeid = '012w000000063q6AAA';
    ci.MailingStreet = '2 Ringo Starr Road';
    ci.MailingCity = 'BedRock';
    ci.MailingPostalCode = 'AL9 3RD';
    insert ci;
    
    
    Opportunity o = new Opportunity();
    o.AccountId = a.Id;
    o.StageName = 'Won';
    o.RecordTypeid = '012w0000000ic3mAAA';
    o.Final_Price_Number__c = 2000;
    o.Business_Unit__c = '1Spatial United Kingdom';
    o.Name = 'Test';
    o.Opportunity_Type__c = 'Contract Renewal';
    O.CurrencyIsoCode ='GBP';
    o.Contract_Type__c = 'Framework';
    o.Estimated_Value_Number__c = 10000;
    o.Opportunity_Submission_Date__c = Date.TODAY();
    o.CloseDate = Date.TODAY() +2;
    o.Probability__c = '80-99%';
    o.Purchase_Order__c = '2L3454';
    o.Solution_Summary__c = 'Hardware';
    o.Description = 'Update Contact role';
    o.Opportunity_Process_Stage__c= 'Opportunity Submitted to Customer: Approved`';
    o.Ownerid = '005w0000004ExSiAAK';
    insert o;
    
        
     OpportunityContactRole cr = new OpportunityContactRole();
     cr.Opportunityid = o.id;
     cr.Role = 'Administrator';
     cr.Contactid = c.id;
     cr.IsPrimary = true;
     insert cr;
     
     OpportunityContactRole ocr1 = new OpportunityContactRole();
     ocr1.ContactId = ci.Id;
     ocr1.OpportunityId = o.Id;
     ocr1.IsPrimary = FALSE;
     ocr1.Role = 'Decision Maker';
     insert ocr1;
     
    
     Id pricebookId = Test.getStandardPricebookId();
     Product2 prod = new Product2();
     prod.Name = 'Product 2';
     prod.ProductCode = 'Pro-2';
     prod.isActive = true;
     prod.Revenue_Type__c = 'Services';
     prod.Product_Heading__c = '1Edit';
     insert prod;

     PricebookEntry pbEntry = new PricebookEntry();
     pbEntry.Pricebook2Id = pricebookId;
     pbEntry.Product2Id = prod.Id;
     pbEntry.UnitPrice = 100.00;
     pbEntry.IsActive = true;
     insert pbEntry;

     OpportunityLineItem oli = new OpportunityLineItem();
     oli.OpportunityId = o.Id;
     oli.quantity = 1;
     oli.PricebookEntryId = pbEntry.Id;
     oli.TotalPrice = oli.quantity * pbEntry.UnitPrice;
     insert oli;

    o.StageName = 'Won';
    update o;

}
}

do you have any ideas