0

Salesforce Documentation indicates that when the account field is edited on an Opportunity, related Partner records are deleted. You can find this information in the notes section here.

I have tried capturing these values in a trigger on the Opportunity and re-inserting them, As well as writing a trigger on the Partner object. Unfortunately neither of these workarounds have been successful. I don't want these Partner records automatically deleted. Is there anyway around this default behavior?

public without sharing class OpportunityTriggerHandler
extends GenericTriggerHandler
{
    public override void BeforeUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems){
        OpportunityTriggers.cachePartnersOnAccountChange((Map<Id, Opportunity>) oldItems, (Map<Id, Opportunity>) newItems);
    }
    public override void AfterUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems)
    {
        PartnerHelper.reInsertExistingPartners();
    }
}
public static void cachePartnersOnAccountChange(Map<Id, Opportunity> oldOpps, Map<Id, Opportunity> newOpps){
        
List<Id> processOpportunities = new List<Id>();

        for(Opportunity opp : newOpps.values()){
            if(oldOpps.get(opp.Id) != null && oldOpps.get(opp.Id).AccountId != opp.AccountId){
                processOpportunities.add(opp.Id);
            }
        }

        PartnerHelper ph = new PartnerHelper(processOpportunities);
    }
public with sharing class PartnerHelper {

    public static List<Partner> existingPartners;

    public partnerHelper(List<Id> opportunityIds){
        existingPartners = new List<Partner>();
        for(Partner p : [Select AccountFromId, AccountToId, IsPrimary, OpportunityId, ReversePartnerId, Role
                            From Partner Where OpportunityId = :opportunityIds]){
            existingPartners.add(new Partner(AccountToId = p.AccountToId, IsPrimary = p.IsPrimary, OpportunityId = p.OpportunityId, Role = p.Role));
        }
    }

    public static void reInsertExistingPartners(){
        insert existingPartners;
    }

}
2
  • Can you include the trigger code that you wrote when you tried to capture and re-insert them? This is possible - I've done it myself
    – Aidan
    Jul 28, 2020 at 15:09
  • hi, @Aidan. I added the latest iteration of code. I get an error during the after, seems like the partner records aren't deleted until after all of the opportunity triggers have run.Thanks for taking the time to review.
    – joshii
    Jul 29, 2020 at 16:49

1 Answer 1

1

You can solve this with a trigger but there are two gotchas:

First, when you manually add a Partner to an Opportunity, Salesforce implicitly adds the current Opportunity.AccountId as another partner. You can see this via SOQL, but not via the UI and it doesn't seem to happen in Apex tests. So, I would advise that you exclude this when you're caching the ones to reconstitute. Otherwise it starts generating unexpected Partners.

Second, Workflows and PB can confuse matters. This means your trigger can re-enter. Due to the wonderful way that WF interacts with Apex, it can run your trigger twice in the same transaction with the same Trigger.old and Trigger.new. This can mean that you cache the Partners in a before context, SF deletes them, you create them in after, WF fires, you cache them again, SF doesn't delete them, you try to create them again and hit the wall.

So, before you re-insert, you should check that all the Partners you plan to insert don't already exist and are not the Opportunity.AccountId of the Opportunity in the after context.

With those measures in place, I've had code like yours working. If you get specific errors, by all means post them up.

1
  • Hey appreciate you sharing these details. I made some changes based on your suggestions. Thanks for the help!
    – joshii
    Jul 29, 2020 at 22:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .