Scenario:
I have a trigger that will fire whenever a Primary Campaign Changes on an Opportunity by comparing trigger.old and trigger.new values of CampaingID,
Issue:
When I changed the campaign on the opportunity to point to a different campaign, the trigger did not fire when I debugged it I found that trigger.old value and trigger.new value of Campaign are the SAME
(I checked the logs there is no recursion problem all classes are called only once).
Any reason why this might be happening?
SideNote : I have WFRs firing on Opportunity as well
trigger MasterOpportunityTrigger on Opportunity(after update)
{
if (Trigger.isUpdate)
{
if(triggerHelper.isAfterUpdateFirstRun == true)
triggerHelper.isAfterUpdateFirstRun = false;
//Campaign changed for Opportunity update the old campaign
CampChangeRollup Camp = new CampChangeRollup(trigger.oldmap,trigger.newmap);
Camp.FCampRollUp();
system.debug('*************CampChangeRollup Class Execute After Update');
}
}
public class CampChangeRollup
{
private Map<Id, Opportunity> oldOpps;
private Map<Id, Opportunity> newOpps;
private Map<Id,Opportunity> CampIdOpp = new Map<Id,Opportunity>();
private list<Opportunity> Opplst = new list<Opportunity>();
private list<Opportunity> delOpplst = new list<Opportunity>();
public CampChangeRollup(Map<Id, Opportunity> oldTriggerOpps, Map<Id, Opportunity> newTriggerOpps)
{
if(oldTriggerOpps != Null)
oldOpps = oldTriggerOpps;
else
oldOpps = new Map<Id,Opportunity>();
if(newTriggerOpps != Null)
newOpps = newTriggerOpps;
else
newOpps = new Map<Id,Opportunity>();
for(Opportunity opp : newOpps.values())
{
// Access the "old" record by its ID in Trigger.oldMap
// Opportunity oldOpp;
Id newOppCampId;
Id oldOppCampId;
if(!oldOpps.isEmpty())
oldOppCampId = oldOpps.get(opp.Id).CampaignId;
if(opp.CampaignId != null)
newOppCampId = opp.CampaignId;
system.debug('oldOppCampId'+' '+oldOppCampId+' '+'newOppCampId'+' '+newOppCampId);
//Only when Campaign is changed
if(newOppCampId != oldOppCampId)
CampIdOpp.put(oldOppCampId,opp);
}
}
public void FCampRollUp()
{
try
{
if(CampIdOpp!= null)
{
for(Campaign Camp : [select id from Campaign where id =:CampIdOpp.keyset()])
{
Id OppId = CampIdOpp.get(Camp.id).id;
String soql = CloningUtils.getCreatableFieldsSOQL('Opportunity','id = :OppId ');
system.debug('returned SOQL'+ soql);
Opportunity O = (Opportunity)Database.query(soql);
Opportunity Od = O.clone(false, true);
Od.CampaignId = Camp.Id;
Od.Amount = 1;
system.debug('Opportunity tobe deleted'+ Od.id+Od.name+Od.CampaignId);
Opplst.add(Od);
}
if(Opplst.size()>0)
{
insert Opplst;
system.debug('Opplst'+Opplst);
system.debug('Dummy Opportunity Inserted for Campaign Changed Opportunity'+ Opplst+Opplst[0].id+Opplst+Opplst[0].CampaignId);
}
}
} catch(Exception error){ }
}
}
Best Answer
One of the possible scenario here is usage of multiple triggers with DML. Let's look at the example below.
Trigger B:
With its handler:
Due to Stage update, will get following logs:
But if we add new Trigger for Opportunity:
Handler :
Console log:
As we can see there is no Magic for B Handler. DML we've made in trigger C has created new trigger event, and this event has higher priority that DML from UI. (I suppose Salesforce is using Stack for this.) That's why we have same field values while they're arriving to Trigger B If you disable recursion functionality, you'll see that values from UI arrive to trigger B with counter = 1. Just make sure you have one trigger and as many handlers as you want.
I thought that order is dependent on trigger time creation or its name, but it's not