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
RahulRahul 

hello friends i want to write a schedule class updating boolean pickist to true or false

I want to write a schedule class. There is a Picklist field Named Boolean with values as true or false which i have created on contact .We have sent 2000+ Emails for all contacts. There Related list of the Contacts which is Activity history has the subject as 'Mass Email' .I want to set the boolen value to true  when the subject in the Task is 'Mass Email'. I tried to do this with the help of a Trigger but its only working when i manually go and create a task, edit a task or complete a task. If iam trying to send it from Mass Email Application the activity history is created and but its not updating the boolean value. This is the following Trigger which i wrote

trigger updatestatus on Task (after insert,after update,before insert) {
set<id> setid = new set<id>();
list<contact> lstcon = new list<contact>();
for(task t :trigger.new){

setid.add(t.whoid);
}
for(contact cc :[select id,boolean__C,(select subject from tasks where subject='Mass Email: Fourth Followup for Accounts New' ) from contact where id=:setid]){
For(task t1 :trigger.new){
if(t1.subject=='Mass Email: Fourth Followup for Accounts New'){
Contact cc1 = new contact();
cc1.id=cc.id;
cc1.boolean__c='True';
lstcon.add(cc1);

}
update lstcon;
}

}

}

Iam thinking to write a schedule class which will run at a particular time and update the old contact records at once to boolean ='True'  and check for the new ones also. Any help will be Really Appretiated. Thanks
naresh babu 43naresh babu 43
How to invoke webservice through batch apex and send records information in json format through external system
please suggest me?
Zuinglio Lopes Ribeiro JúniorZuinglio Lopes Ribeiro Júnior
Hello,

I've created an example (didn't test) using a Batch class that you can schedule. Here are some considerations about your requirement:

1 - Consider changing the type of field Boolean__c from a picklist to a checkbox. Checkbox field represents a boolean. If not possible, try giving to the field a more meaningful name instead of just "Boolean", this will make more understandable for further reference.
2 - Batch classes are a safe choice when dealing with a high volume of records. Maybe you can do it using a Schedulable interface or a Queueable, is up to you (the query will remain the same).
3 - If this process is for a daily basis use, consider creating an Event Log to help to monitor possible issues.
4 - You can create a metadata to control how often the batch should execute.
5 - There is another approach where you can query the tasks instead, but it would also require another controlling field in the task in order to avoid querying data that was already processed.
 
global class ExampleBatch implements Database.Batchable<sobject> {

    global  Database.QueryLocator start(Database.BatchableContext ctx) {                  
        return Database.getQuerylocator([SELECT Id,
												Boolean__c,
												(SELECT Id FROM Tasks Subject = 'Mass Email: Fourth Followup for Accounts New') 
										FROM 	Contact
										WHERE 	Boolean__c = 'False']); 
    }
    
    global void execute(Database.BatchableContext BC, List<Contact> contacts ) {
    
		Set<Contact> contactsToUpdate = new Set<Contact>();
		
		for (Contact con : contacts) {
			if (con.Tasks.size() > 0) {
				con.Boolean__c = 'True';
				contactsToUpdate.add(con);	
			}			
		}
		
		Database.SaveResult[] saveResults = Database.update(new List<Contact>(contactsToUpdate), false);
		
		// Optional code
		// Iterate through each returned result
		for (Database.SaveResult sr : saveResults) {
			if (sr.isSuccess()) {
				// Operation was successful, so get the ID of the record that was processed
				System.debug('Successfully inserted account. Account ID: ' + sr.getId());
			} else {
				// Operation failed, so get all errors                
				for(Database.Error err : sr.getErrors()) {
					System.debug('The following error has occurred.');                    
					System.debug(err.getStatusCode() + ': ' + err.getMessage());
					System.debug('Contact fields that affected this error: ' + err.getFields());
				}
			}
		}
    }
 
    global void finish(Database.BatchableContext BC) {
		
        // Check batch status - IF COMPLETED then 
        AsyncApexJob job = [SELECT 	Id, Status
                            FROM 	AsyncApexJob 
                            WHERE Id = :bc.getJobId()];        
        
        // Chaining Batch execution
        if (job.Status == 'Completed') {
            
            // If post processing retry is not scheduled then schedule it
            List<CronTrigger> scheduledJobs = [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name = 'ExampleBatch'];
            
            if (scheduledJobs.isEmpty() || Test.isRunningTest()) {

				// You can create a metadata to control how often the batch should execute
				Integer minutes = 30;
				Integer chunkSize = 200;
			
				System.scheduleBatch(new ExampleBatch(), 'ExampleBatch', minutes, chunkSize);
			}
		}
	
    }

}

When you schedule the batch it will reschedule itself (chaining) based on the parameters in the finish method. To start the batch for the first time you can schedule it (System.scheduleBatch(new ExampleBatch(), 'ExampleBatch', 30, chunkSize);) or execute directly (Database.executeBatch(new ExampleBatch());) from the execute anonymous window on the developer console.

Hope to have helped!

Regards.

Don't forget to mark your thread as 'SOLVED' with the answer that best helps you.