[SalesForce] How to create schedule batch apex which returns list of object records

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.

Best Answer

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.)

Related Topic