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
ShikibuShikibu 

OpportunitySplit : send email to opportunity team upon any change

I'm stumped by this, because there may be multiple triggers fired. Really what I want is a trigger on the opp when any related opportunitysplit is inserted, updated, or deleted (that's how OpportunityLineItem works). But OpportunitySplit does not seem to fire Opportunity triggers.

I can't figure out how to use the OpportunitySplit trigger, because multiple triggers may fire (insert, update, delete), and I only want to send one email when any aspect of the OpportunitySplit changes.
Adilson Arcoverde JrAdilson Arcoverde Jr
Hi Shikibu,

I guess the best approach is to create a new trigger on OpportunitySplit handling all those events you told. Try this code:
trigger OpportunitySplitTrigger on OpportunitySplit (after insert, after update, after delete) {
    Set<String> oppsIds = new Set<String>();
    
    if( (Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {

        for( OpportunitySplit split : Trigger.new ) {
            oppsIds.add(split.OpportunityId);
        }
    } else if( Trigger.isDelete && Trigger.isAfter ) {
        for( OpportunitySplit split : Trigger.old ) {
            oppsIds.add(split.OpportunityId);
        }    
    }
    
    List<OpportunityTeamMember> oppsMembers = [Select Id, UserId, User.Email from OpportunityTeamMember where OpportunityId in :oppsIds];
    Set<String> emailAddresses = new Set<String>();
    for( OpportunityTeamMember member : oppsMembers ) {
        emailAddresses.add( member.User.Email );
    }
    
    // Add your logic to send an email here. You can use emailAddresses.
}

You just need to add your logic to send the email.

Let me know if I can help with anything else. If you find the solution useful, please mark as Best Answer to help others developers too.

Regards.
ShikibuShikibu
Isn't it the case that, if some opportunitysplits were inserted, some were deleted and some were edited, your code will send three emails? The trigger will be invoked three times.
Adilson Arcoverde JrAdilson Arcoverde Jr
Hi,

The trigger has to be invoked three times, since you are handling three different events. The only solution I can imagine for your case (assuming you want to email team members only once), is to schedule a job that will run in the frequency you desire (once a hour, once a minute, etc.).

So to archieve that, you have to create a new custom field on Opportunity (IsSplitChanged__c) wich will be writter by OpportunitySplitTrigger.

Please consider the following code:

Trigger
trigger OpportunitySplitTrigger on OpportunitySplit (after insert, after update, after delete) {
    Set<String> oppsIds = new Set<String>();
    
    if( (Trigger.isInsert || Trigger.isUpdate) && Trigger.isAfter) {

        for( OpportunitySplit split : Trigger.new ) {
            oppsIds.add(split.OpportunityId);
        }
    } else if( Trigger.isDelete && Trigger.isAfter ) {
        for( OpportunitySplit split : Trigger.old ) {
            oppsIds.add(split.OpportunityId);
        }    
    }
    
    List<Opportunity> opps = [Select Id, IsSplitChanged__c from Opportunity where Id in :oppsIds];
    for( Opportunity opp : opps ) {
        opp.IsSplitChanged__c = true;
    }
    update opps;
}
Schedulable
global class SplitNotificationSch implements Schedulable {
   global void execute(SchedulableContext SC) {
      List<Opportunity> opps = [Select Id, (Select User.Email from OpportunityTeamMembers) from Opportunity where IsSplitChanged__c = true];
      Set<String> emailAddresses = new Set<String>();
       for( Opportunity opp : opps ) {
           for( OpportunityTeamMember member : opp.OpportunityTeamMembers ) {
               emailAddresses.add( member.User.Email );
           }
           
           // add code to send the email here
           opp.IsSplitChanged__c = false;
       }
       update opps;
   }
}