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
vickySFDCvickySFDC 

How to Inactive account status no activity assigned?

Hi All,

  I have requirement for Inactive account  if there is no activity like(task,event) assigned for last 30 days for that account.Anyone help on this scenario.Give some sample code.How to implement.

Thanks,
vicky
 
Arun KumarArun Kumar
Hi Vicky,

I think Batch class and a scheduler will work for it.

Scheduler will run everyday and will check those records who are eligble for this condition i.e no activity for more than 30 days.

Thanks,
​Arun
Lars NielsenLars Nielsen
Arun is correct. Batch is a great option. In this case, here is a simple batch class that takes number of days in and runs a query to update the accounts. I don't know what specificially you are trying to update (i.e. maybe a status field) but you would just replace that line I have commented out.
global class CleanupInactiveAccounts implements Database.Batchable<SObject>, Database.AllowsCallouts, Database.Stateful {

    global final integer daysOfInactivity;
    
    global CleanupInactiveAccounts (integer daysOfInactivity)
    {
      this.daysOfInactivity = daysOfInactivity;   
    }
    
    global Database.Querylocator start(Database.BatchableContext bc) { 
        
        
        Datetime earliestDateToKeep = Datetime.now().addDays(-1 * daysOfInactivity); 

       string query = 'select Id from Account LastActivityDate < :' + earliestDateToKeep +'Order by LastActivityDate ASC limit ';
        
        Database.Querylocator queryLocator = null;
        try {
            queryLocator = Database.getQueryLocator(query);         
        }
        catch (Exception ex) {

        }
              
        return queryLocator;
    } 

    
	global void execute(Database.BatchableContext BC, List<sObject> scope){
    	List<Account> accns = new List<Account>();

   		for(sObject s : scope){Account a = (Account)s;

				//a.Status =  xyz; //**** set your status here ****// 
            	accns.add(a);
            
        }
        
        try
        {

			update accns;
        }
        catch(DMLException ex)
        {
        	
        }
    
	}
    
    global void finish(Database.BatchableContext bc) {
    }
    
   
    
}

You can see by looking at the Dev Console that when I pass in 30, it grabs things with a date less than 2015-12-21 22:03:30Debug log

You can then setup a batch job to call this on the fly or nightly, weekly.

Example of a one-time run:
CleanupInactiveAccounts  cleanupInactiveBatch = new CleanupInactiveAccounts(30);
Database.executeBatch(cleanupInactiveBatch);

Some great resources:
​https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_1.htm
https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_3.htm
 
Lars NielsenLars Nielsen
One last one if you want to schedule through the UI: 
https://developer.salesforce.com/docs/atlas.en-us.198.0.apex_workbook.meta/apex_workbook/apex_scheduling_3.htm#apex_scheduling_3
vickySFDCvickySFDC
Thanks for Quick reply Nielson.
I will check and let me know

Thanks,
​vicky
Lars NielsenLars Nielsen
If you are satisfied please mark as the best answer so the subject gets closed out -  you can always follow up with questions after the fact
vickySFDCvickySFDC
Nielsen,

    This code not working.I have tested this code using lastactivitydate.
Scenario:
I have added new  account and checking for if no activity assigned for last 3 days then my custom field has Active check box made as false.

CODE:

global class Inactiveaccountstatus implements Database.Batchable<SObject>, Database.Stateful {
    global final integer activitydays;
    global Inactiveaccountstatus (integer activitydays)
    {
        this.activitydays = activitydays;   
    }
    
    global Database.Querylocator start(Database.BatchableContext bc) { 
        Date oldactvitydate = system.today().addDays(-1 * activitydays);
        
        string query = 'select Id from Account WHERE LastActivityDate <: oldactvitydate AND LastModifiedDate <: oldactvitydate Order by LastActivityDate ASC ';
        return Database.getQueryLocator(query); 
    }
    
    global void execute(Database.BatchableContext BC, List<sObject> scope){
        List<Account> lstacc = new List<Account>();

        for(sObject s : scope){Account a = (Account)s;
            a.Active__c = false;
            lstacc.add(a);
        }
        
        try
        {
            system.Debug(' lstacc +++++++++'+lstacc);
            update lstacc;
        }
        catch(DMLException ex)
        {
            
        }
    
    }
    
    global void finish(Database.BatchableContext bc) {
    }
}

Please help me on this.
Thanks,
vicky
Lars NielsenLars Nielsen
 
  1. Can you show us how you are calling this code?
  2. What are you passing in for the days param?
  3. If you look at the stack trace is it returning results from the query? i.e. did it find accounts that matched the criteria
Just as a simple test I took the query lines and ran them in the Dev console on my account to make sure that the query returns results:
 
Integer activitydays = 3; //you should be passing this in or hardcoding it
Date oldactvitydate = system.today().addDays(-1 * activitydays);
        
List<Account> acctsList = [select Id from Account WHERE LastActivityDate <: oldactvitydate AND LastModifiedDate <: oldactvitydate Order by LastActivityDate ASC ];

After running the following in my order I get 5 records, which is correct because the 6th account has an activity that I just added to it.

5 rows returned of 6

You should be open to open the Setup > Dev Console > Debug > Open Execute Anonumous  and run the class like I gave in the example above but in your case you want 3  so you pass in 3 instead of 30

Dev Console
CleanupInactiveAccounts  cleanupInactiveBatch = new CleanupInactiveAccounts(3);
Database.executeBatch(cleanupInactiveBatch);

I guess in your case it would be 
 
Inactiveaccountstatus  cleanupInactiveBatch = new Inactiveaccountstatus(3);
Database.executeBatch(cleanupInactiveBatch);

When you run this you'll see the debug logs and you should be able to see why it is not working. I am just trying to see where it is failing.