Hi I am new in salesforce, and I want to create a Schedule Batch Apex that will query for any Contact and For each Contact returned create an Opportunity.
I have written the following code for this:
global class ScheduleContact implements Database.Batchable<SObject>
{
List<contact> contactList;
global Database.queryLocator start(Database.BatchableContext ctx)
{
contactList= new List<contact>([Select Con.FirstName,Con.LastName,Con.AccountId,Con.Contract_End_Date__c From contact con where Con.Payment_Type__c = 'Paid In Full' AND Con.Contract_End_Date__c >= LAST_N_DAYS:60]);
return Database.getQueryLocator(contactList);
}
global void execute(Database.BatchableContext BC, List<contact> contactList )
{
//for creating new opportunity.
List<Opportunity> newOpps=new List<Opportunity>();
for(Contact c: contactList)
{
Opportunity opp=new Opportunity();
opp.Name=c.FirstName+c.LastName+'Opportunity';
opp.CloseDate=c.Contract_End_Date__c;
opp.Type='Renewal';
opp.StageName='Met';
opp.AccountId=c.AccountId;
newOpps.add(opp);
}
insert newOpps;
}
global void finish(Database.BatchableContext BC)
{
}
}
But it gives the following error:
Compile Error: Argument must be an inline query at line 8 column 16
which is in line
return Database.getQueryLocator(contactList);
Please tell me how to write code for such a problem can we write code for batch apex that returns list object as i do in above example.
Attribution to: user7717
Possible Suggestion/Solution #1
I rewrote your batch class to the way I write batch Apex - I hope this helps.
global class ScheduleContact implements Database.Batchable<SObject> {
global Database.queryLocator start(Database.BatchableContext ctx) {
DateTime theDateTime = System.now().addDays(-60);
String query = 'Select FirstName, LastName, AccountId, Contract_End_Date__c';
query += ' FROM Contact WHERE Payment_Type__c = \'Paid In Full\'';
query += ' AND Contract_End_Date__c >= :theDateTime';
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<sObject> scope) {
List<Contact> contactList = (List<Contact>)scope;
//for creating new opportunity.
List<Opportunity> newOpps = new List<Opportunity>();
for (Contact c : contactList) {
Opportunity opp = new Opportunity();
opp.Name = c.FirstName + ' ' + c.LastName + ' Opportunity';
opp.CloseDate = c.Contract_End_Date__c;
opp.Type = 'Renewal';
opp.StageName = 'Met';
opp.AccountId = c.AccountId;
newOpps.add(opp);
}
insert newOpps;
}
global void finish(Database.BatchableContext BC) {
}
}
I am using batchable, making a dynamic Apex query string, passing a list to the execute, casting it to a list and then working through that list to make new Opportunities.
(Edit: Thanks to @dphil for noticing my unused variable - removed it.)
Attribution to: DavidSchach
Possible Suggestion/Solution #2
Since you want to pass a collection, you could use Iterable,
global Iterable<Contact> start(Database.BatchableContext BC) {
contactList= new List<contact>([Select Con.FirstName,Con.LastName,Con.AccountId,Con.Contract_End_Date__c From contact con where Con.Payment_Type__c = 'Paid In Full' AND Con.Contract_End_Date__c >= LAST_N_DAYS:60]);
return contactList;
}
Attribution to: anmrk
Possible Suggestion/Solution #3
Can you modify your start method as below
global class ScheduleContact implements Database.Batchable<SObject>
{
global Database.queryLocator start(Database.BatchableContext ctx)
{
return Database.getQueryLocator([Select Con.FirstName,Con.LastName,Con.AccountId,Con.Contract_End_Date__c From contact con where Con.Payment_Type__c = 'Paid In Full' AND Con.Contract_End_Date__c >= LAST_N_DAYS:60]);
}
global void execute(Database.BatchableContext BC, List<contact> contactList)
{
//for creating new opportunity.
List<Opportunity> newOpps=new List<Opportunity>();
for(Contact c: contactList)
{
Opportunity opp=new Opportunity();
opp.Name=c.FirstName+c.LastName+'Opportunity';
opp.CloseDate=c.Contract_End_Date__c;
opp.Type='Renewal';
opp.StageName='Met';
opp.AccountId=c.AccountId;
newOpps.add(opp);
}
insert newOpps;
}
global void finish(Database.BatchableContext BC)
{
}
}
Here I replaced your collection with the the query itself in the argument which Database.getQueryLocator() takes.
Hope it resolves your issue.
EDIT:I have updated the code including @keith's comment
Attribution to: codebandit
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/32261