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
TheReportDoctorTheReportDoctor 

Using @future notation... how does it work?

Why am I getting the error "Error: Compile Error: Unsupported parameter type SOBJECT:Provisioning__c at line 3 column 24" when I try to save this code in my dev edition?  The code works without the "@future".

 

global class provision { @future public static void updateEstDates (provisioning__c currentRecord ){ String opportunityID = currentRecord.Opportunity__c; String provisioningId = currentRecord.Id; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

Best Answer chosen by Admin (Salesforce Developers) 
JimRaeJimRae

According to the documentation:

 

Methods with the future annotation have the following limits:
• No more than 10 method calls per Apex invocation

Note: Asynchronous calls, such as @future or executeBatch, called in a startTest, stopTest block, do not count against your limits for the number of queued jobs.

• Methods with the future annotation can execute 100 SOQL queries when they are in the context of a testMethod
• No more than 200 method calls per Salesforce.com license per 24 hours
• The parameters specified must be primitive dataypes, arrays of primitive datatypes, or collections of primitive datatypes.
• Methods with the future annotation cannot take sObjects or objects as arguments.
• Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.

 

I think in your code, you appear to be passing an object (provisioning__c), which would not be allowed.

What you could do, is pass the ID for the Provisioning__c object to the future method, and then query for it again inside your future method.  Remember to query for any fields you are planning to reference inside your method.

 

 

global class provision { @future public static void updateEstDates (ID currentRecordid ){ String provisioningId = currentRecordId; Provisioning__c currentRecord = [select id,Opportunity__c from Provisioning__c where id =:provisioningId]; String opportunityID = currentRecord.Opportunity__c; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

 

 

All Answers

JimRaeJimRae

According to the documentation:

 

Methods with the future annotation have the following limits:
• No more than 10 method calls per Apex invocation

Note: Asynchronous calls, such as @future or executeBatch, called in a startTest, stopTest block, do not count against your limits for the number of queued jobs.

• Methods with the future annotation can execute 100 SOQL queries when they are in the context of a testMethod
• No more than 200 method calls per Salesforce.com license per 24 hours
• The parameters specified must be primitive dataypes, arrays of primitive datatypes, or collections of primitive datatypes.
• Methods with the future annotation cannot take sObjects or objects as arguments.
• Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.

 

I think in your code, you appear to be passing an object (provisioning__c), which would not be allowed.

What you could do, is pass the ID for the Provisioning__c object to the future method, and then query for it again inside your future method.  Remember to query for any fields you are planning to reference inside your method.

 

 

global class provision { @future public static void updateEstDates (ID currentRecordid ){ String provisioningId = currentRecordId; Provisioning__c currentRecord = [select id,Opportunity__c from Provisioning__c where id =:provisioningId]; String opportunityID = currentRecord.Opportunity__c; Date maxLastEndDate; List<provisioning__c> steps = [SELECT processStep__c , predecessorStep__c , successorStep__c , Est_Start_Date__c , Est_End_Date__c , Interval__c FROM provisioning__c WHERE Opportunity__c = :opportunityID ORDER BY predecessorStep__c]; for( provisioning__c eachStep: steps) { // track the max last date from those who share my successor maxLastEndDate= null; if (eachStep.predecessorStep__c == 0 && maxLastEndDate == null) { maxLastEndDate = system.today(); } else { for(provisioning__c previousStep: steps) { if (previousStep.processStep__c == eachStep.predecessorStep__c || previousStep.successorStep__c == eachStep.processStep__c) { if (maxLastEndDate < previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue())|| maxLastEndDate == null) { maxLastEndDate= previousStep.Est_Start_Date__c.addDays(previousStep.Interval__c.intValue()); } } } } if (eachStep.ID != provisioningId || (eachStep.ID == provisioningId && eachStep.Est_Start_Date__c == null)) { if (maxLastEndDate != null) { eachStep.Est_Start_Date__c = maxLastEndDate; } else { eachStep.Est_Start_Date__c = system.today(); } // User's should not change Est_End_Dates. Update the Intervals only!! if (eachStep.Interval__c == null) { eachStep.Interval__c = 0 ; } } } try { update steps; } catch (dmlException de) { for (Integer i = 0; i < de.getNumDml(); i++) { Trigger.new[0].AddError(de.getDmlMessage(i)); } } } }

 

 

 

This was selected as the best answer
TheReportDoctorTheReportDoctor

Jim,

 

Thanks for the input.

 

Hugh