You need to sign in to do that
Don't have an account?
@Future Class not Updating Records
Background: This code works as a trigger, but for performance improvements because of how much stuff is going on at our opps with other automation, I wanted to make this an @future since its not time sensitive. This works with our Opportunity and related 'Sales Area' (a standard and secondary) which in turn have lookups to the user table based on what role that user plays in the sales area. The idea here is primarily to propogate down the proper info from the sales area down to the opportunity. Just to underline that, as a trigger--this works just dandy!
My trigger
trigger OpportunityReferenceUpdate on Opportunity (after insert, after update) { OpportunityReferenceUpdateClass.processOpportunityReferences(Trigger.newMap.keySet()); }
Apex Class
public class OpportunityReferenceUpdateClass { @future public static void processOpportunityReferences(Set<ID> ops){ List<Opportunity> opl = [select id, Sales_Area__c, Secondary_Sales_Area__c, Inside_Rep_Lookup__c, Field_Rep_Lookup__c, TSE_Lookup__c, Inside_Rep_Split_Lookup__c, Field_Rep_Split_Lookup__c, TSE_Split_Lookup__c from Opportunity where id IN :ops]; Set<id> Field_Rep = new Set<id>(); Set<id> Inside_Rep = new Set<id>(); Set<id> Sales_Associate = new Set<id>(); Set<id> SDR = new Set<id>(); Set<id> TSE1 = new Set<id>(); Set<id> TSE2 = new Set<id>(); Set<Id> saIdSet = new Set<id>(); Set<Id> sa2IdSet = new Set<id>(); for (Opportunity sa : opl){ saIdSet.add(sa.Sales_Area__c); if(sa.Secondary_Sales_Area__c!=null) sa2IdSet.add(sa.Secondary_Sales_Area__c); } Map<Id, Sales_Area__c> saMap = new Map<Id, Sales_Area__C>([select ID, Field_Rep_ID__c, Inside_Rep_ID__c, TSE_ID__c from Sales_Area__c where id IN: saIdSet]); Map<Id, Sales_Area__c> sa2Map = new Map<Id, Sales_Area__C>([select ID, Field_Rep_ID__c, Inside_Rep_ID__c, TSE_ID__c from Sales_Area__c where id IN: sa2IdSet]); for (Opportunity sa : opl){ sa.Inside_Rep_Lookup__c='005G0000006uYgi'; if(sa.Sales_Area__c!=null){ Sales_Area__c salesarea = saMap.get(sa.Sales_Area__C); sa.Inside_Rep_Lookup__c=salesarea.Inside_Rep_ID__c; sa.Inside_Rep_ID__c=salesarea.Inside_Rep_ID__c; if(sa.Inside_Rep_At_Close_ID__c !=null || sa.IsClosed==True) sa.Inside_Rep_Lookup__c=sa.Inside_Rep_At_Close_ID__c; if(sa.Inside_Rep_Overwrite__c!=null) sa.Inside_Rep_Lookup__c=sa.Inside_Rep_Overwrite__c; sa.Field_Rep_Lookup__c=salesarea.Field_Rep_ID__c; sa.Field_Rep_ID__c=salesarea.Field_Rep_ID__c; if(sa.Field_Rep_At_Close_ID__c !=null || sa.IsClosed==True) sa.Field_Rep_Lookup__c=sa.Field_Rep_At_Close_ID__c; if(sa.Field_Rep_Overwrite__c!=null) sa.Field_Rep_Lookup__c=sa.Field_Rep_Overwrite__c; sa.TSE_Lookup__c=salesarea.TSE_ID__c; sa.TSE_ID__c=salesarea.TSE_ID__c; if(sa.TSE_At_Close_ID__c !=null || sa.IsClosed==True) sa.TSE_Lookup__c=sa.TSE_At_Close_ID__c; if(sa.TSE1_Overwrite__c!=null) sa.TSE_Lookup__c=sa.TSE1_Overwrite__c; } if(sa.Secondary_Sales_Area__c != null){ Sales_Area__c salesarea2 = sa2Map.get(sa.Secondary_Sales_Area__C); sa.Inside_Rep_Split_Lookup__c=salesarea2.Inside_Rep_ID__c; sa.Inside_Rep_Split_Id__c=salesarea2.Inside_Rep_ID__c; if(sa.Inside_Rep_Split_At_Close_ID__c !=null || sa.IsClosed==True) sa.Inside_Rep_Split_Lookup__c=sa.Inside_Rep_Split_At_Close_ID__c; sa.Field_Rep_Split_Lookup__c=salesarea2.Field_Rep_ID__c; sa.Field_Rep_Split_ID__c=salesarea2.Field_Rep_ID__c; if(sa.Field_Rep_Split_At_Close_ID__c !=null ||sa.IsClosed==True) sa.Field_Rep_Split_Lookup__c=sa.Field_Rep_Split_At_Close_ID__c; sa.TSE_Split_Lookup__c=salesarea2.TSE_ID__c; sa.TSE_Split_ID__c=salesarea2.TSE_ID__c; if(sa.TSE_Split_At_Close_ID__c !=null || sa.IsClosed==True) sa.TSE_Split_Lookup__c=sa.TSE_Split_At_Close_ID__c; } if(sa.Field_Rep_Overwrite__c != null) Field_Rep.add(sa.Field_Rep_Overwrite__c); if(sa.Inside_Rep_Overwrite__c != null) Inside_Rep.add(sa.Inside_Rep_Overwrite__c); if(sa.TSE1_Overwrite__c != null) TSE1.add(sa.TSE1_Overwrite__c); if(sa.TSE2_Overwrite__c != null) TSE2.add(sa.TSE2_Overwrite__c); } Map<id, User> Field_Rep_Names = new Map<id, User>([Select Name from User Where Id in :Field_Rep]); Map<id, User> Inside_Rep_Names = new Map<id, User>([Select Name from User Where Id in :Inside_Rep]); Map<id, User> TSE1_Names = new Map<id, User>([Select Name from User Where Id in :TSE1]); Map<id, User> TSE2_Names = new Map<id, User>([Select Name from User Where Id in :TSE2]); for (Opportunity sa : opl){ if(sa.Field_Rep_Overwrite__c != null) sa.Field_Rep_Overwrite_text__c = Field_Rep_Names.get(sa.Field_Rep_Overwrite__c).Name; else sa.Field_Rep_Overwrite_text__c =''; if(sa.Inside_Rep_Overwrite__c != null) sa.Inside_Rep_Overwrite_text__c = Inside_Rep_Names.get(sa.Inside_Rep_Overwrite__c).Name; else sa.Inside_Rep_Overwrite_text__c =''; if(sa.TSE1_Overwrite__c != null) sa.TSE1_Overwrite_text__c = TSE1_Names.get(sa.TSE1_Overwrite__c).Name; else sa.TSE1_Overwrite_text__c =''; if(sa.TSE2_Overwrite__c != null) sa.TSE2_Overwrite_text__c = TSE2_Names.get(sa.TSE2_Overwrite__c).Name; else sa.TSE2_Overwrite_text__c =''; } } }
You'll note that on one of the lines I included
sa.Inside_Rep_Lookup__c='005G0000006uYgi';
This was to see if I could simply force a value (which it's not). My apex logs show that this future method is being fired and completing without error. If I intentionally induce errors (like removing fields from my select statement) those errors are reported as expected.
If this fix your issue please accept the solution so that others could be benifited from it.
Thanks
Shashikant
All Answers
I read your code and found
1. There is no Update opl; means noupdate statement to update the opportunity.
2. You should put a condition
if it still does not work then try to put a assert false statemnt to see the opl values.
System.assert( false, opl );
Let me knwo how it goes.
Thanks
Shashikant
If this fix your issue please accept the solution so that others could be benifited from it.
Thanks
Shashikant
+Shashikant,
Please find the modified code. Here, what I am suggesting is, you can implement the same method "processOpportunityReferences" which should not have @future annotation. That way, if the trigger is calling normally then it will call @future method(processOpportunityReferences) and if the trigger is calling in the future context then Sync method(processOpportunityReferencesSync) will execute.
Please do let me know if it helps you.
Regards,
Mahesh
Thank you Mahesh and Shashikant!
Mahesh, my only concern with your if else--is because the trigger is on the opportunity and updates the opportunity, wouldn't it cause an endless loop with your else condition?