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
XIOXIO 

Trigger to count Opportunities related to the Contact

Hello Developers,

I have the trigger below that counts the number of Opportunities that are assigned to the Account and displays them on the Contact redord. I need this trigger to only count the Opportunities that the Contact is assigned to via the Opportunity Contact Role and the field in the Opportunity called STS Currently Engaged is TRUE. Any assistance will be greatly appreciated!!
trigger RollUpSTSOpportunity on Opportunity (after delete, after insert, after update) 
{
    set<Id> setAccountIds = new set<Id>();
    map<Id, Integer> mapAccountToOpp = new map<Id, Integer>();
    List<Contact> lstContactUpdate = new List<Contact>();
    
    if(trigger.isInsert || trigger.isUpdate)
    {
        for(Opportunity o : trigger.new)
        {
            setAccountIds.add(o.AccountId); // take all the related Account Id's in a set from trigger.new in case of insert/update
        }
    }
    else
    {
        for(Opportunity o : trigger.old)
        {
            setAccountIds.add(o.AccountId); // take all the related Account Id's in a set from trigger.old in case of delete
        }
    }
    
    for(Account a : [Select Id, (Select Id From Opportunities) From Account Where Id In :setAccountIds])
    {
        mapAccountToOpp.put(a.Id, a.Opportunities.size()); // add each account id with the number of opportunities related to it
    }
    
    for(Contact c : [Select Id, AccountId, Related_STS_Opportunities__c  From Contact Where AccountId In :mapAccountToOpp.keySet()])
    {
        c.Related_STS_Opportunities__c  = mapAccountToOpp.get(c.AccountId);  // from the contact, we can get the number of opp related to it's parent account
        lstContactUpdate.add(c);
    }
    
    if(lstContactUpdate.size() > 0)
        update lstContactUpdate; // update the contacts
}

 
Best Answer chosen by XIO
rajat Maheshwari 6rajat Maheshwari 6

Hi Harmens,

Below is code snippet to support your use case : - 

trigger RollUpSTSOpportunity on Opportunity (after insert, after update) 
{
    set<Id> setAccountIds = new set<Id>();
    set<Id> setOppId = new Set<Id>();
    map<Id, Double> mapAccountToOpp = new map<Id, Double>();
    Map<String,OpportunityContactRole> mp_ContRole = new Map<String,OpportunityContactRole>();
    List<Contact> lstContactUpdate = new List<Contact>();
    List<account> acc_List = new List<account>();
    

for(OpportunityContactRole opContRole : [Select Id,OpportunityId from OpportunityContactRole where OpportunityId IN : Trigger.newMap.keyset()])
     {
         mp_ContRole.put(opContRole.OpportunityId,opContRole);
     }

   if(trigger.isInsert || trigger.isUpdate)
    {
        for(Opportunity o : trigger.new)
        {
           if(mp_ContRole!=null && mp_ContRole.containsKey(o.id) &&  o.STS_Currently_Engaged__c==true)
                  setAccountIds.add(o.AccountId);
        }
    }
    
for(AggregateResult agg : [Select accountId,Count(Id) from Opportunity where accountId IN:setAccountIds group by accountId])
      {
           mapAccountToOpp.put((Id)agg.get('accountId'),(Double)agg.get('expr0'));
      }

for(Account acc : [Select Id,Number_of_Opportunities from Account where Id IN:setAccountIds])
    {
       if(mapAccountToOpp!=null && mapAccountToOpp.containsKey(acc.Id))
            {
                 acc.Number_of_Opportunities = mapAccountToOpp.get(acc.id);
                 acc_List.add(acc);
            }
     }

if(acc_List!=null && acc_List .size()>0)
   update acc_List ;


}
This logic will roll up those count of opportunity who are associated with contact  to Account .

All Answers

DixitDixit
Ir you are using the related list of "role contact", when you assign a role and a contact to an opp if you go to the contact you assigned, you can see in the related list the opportunities it has. 

Just query the opps in every contact WHERE STS Currently Engaged == True. The size of that list should be the number of opps it has.

Or am I getting it wrong?
XIOXIO
Hi Dixit, 

Thank you for the reply.

How do "query the opps in every contact WHERE STS Currently Engaged == True. The size of that list should be the number of opps it has."
DixitDixit
list<contact> contacts = [SELECT id, (SELECT id, name FROM opportunities) FROM contact WHERE sts_currently_engaged__c = True];

if(contacts.size()>0){
for(contact c : contacts){
  c.number_of_opportunities__c = c.opportunities.size();   //should be the name of the field you are using to count the opps.
}
}

if(contacts.size()>0){
  update contacts;
}


Something like that.
DixitDixit
sorry, you need to add to the query the "number_of_opportunities__c" field (or however you call it) to use it later. 
rajat Maheshwari 6rajat Maheshwari 6

Hi Harmens,

Below is code snippet to support your use case : - 

trigger RollUpSTSOpportunity on Opportunity (after insert, after update) 
{
    set<Id> setAccountIds = new set<Id>();
    set<Id> setOppId = new Set<Id>();
    map<Id, Double> mapAccountToOpp = new map<Id, Double>();
    Map<String,OpportunityContactRole> mp_ContRole = new Map<String,OpportunityContactRole>();
    List<Contact> lstContactUpdate = new List<Contact>();
    List<account> acc_List = new List<account>();
    

for(OpportunityContactRole opContRole : [Select Id,OpportunityId from OpportunityContactRole where OpportunityId IN : Trigger.newMap.keyset()])
     {
         mp_ContRole.put(opContRole.OpportunityId,opContRole);
     }

   if(trigger.isInsert || trigger.isUpdate)
    {
        for(Opportunity o : trigger.new)
        {
           if(mp_ContRole!=null && mp_ContRole.containsKey(o.id) &&  o.STS_Currently_Engaged__c==true)
                  setAccountIds.add(o.AccountId);
        }
    }
    
for(AggregateResult agg : [Select accountId,Count(Id) from Opportunity where accountId IN:setAccountIds group by accountId])
      {
           mapAccountToOpp.put((Id)agg.get('accountId'),(Double)agg.get('expr0'));
      }

for(Account acc : [Select Id,Number_of_Opportunities from Account where Id IN:setAccountIds])
    {
       if(mapAccountToOpp!=null && mapAccountToOpp.containsKey(acc.Id))
            {
                 acc.Number_of_Opportunities = mapAccountToOpp.get(acc.id);
                 acc_List.add(acc);
            }
     }

if(acc_List!=null && acc_List .size()>0)
   update acc_List ;


}
This logic will roll up those count of opportunity who are associated with contact  to Account .
This was selected as the best answer