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
vishal yadav 78vishal yadav 78 

how to create a batch class users who are not logged in for 90 days be auto matically de-activated

Hi folk,

i want to write a batch class for users , like which users are not logged in for 30 days and created but not not logged in within 5day, be auto matically de-activated. Field should be Last Deactivated.
How to do?  Please help me out frields as soon as possible.
schenario is--

select field from user where last loginedate < custom setting and profile in (custom settings)) and username not in (custom setting)

select field from user where last logindate is null and profile in (custom setting) and username not in (custom setting) and created date<-----

isActive--false
date--currect date
 
Khan AnasKhan Anas (Salesforce Developers) 
Hi Vishal,

Greetings to you!

Please try the below code, I have tested in my org and it is working fine. Kindly modify the code as per your requirement.
 
global class deactivateUsers implements Database.Batchable<SObject>
{

   
   
        dateTime dt = date.today()-90;
       public String query = 'SELECT Name, LastLoginDate, Id From User WHERE IsActive = true AND LastLoginDate < +dt  and profile<>"System Adminstrator" ';
    

    global Database.querylocator start(Database.BatchableContext bc)
    {
       return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext bc,List<User> scope)
    {
        List<User> userList = new List<User>();
        
        for(User s:scope)
        {
            User u =(user)s;
            userList.add(u);
        }
        
        if(userList.size() > 0)
        {
            for(User usr : userList)
            {
                usr.isActive = false;
            }
        }
        update userList;
    }

    global void finish(Database.BatchableContext bc)
    {
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob 
                          WHERE Id = :BC.getJobId()];

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('Apex Job Status: ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Harsha SekharHarsha Sekhar
global class Batch_apex_for_user_deactivation Implements Schedulable {
    
    global void execute(SchedulableContext sc)
   		 {	
         	//Call method here

          }
Use this to make a batch class , send the flow outside and get details from User and user login objects (two objects are different)
*Remember LastLogin Date datatype is not date its DateTime may be changes required.*
myDate.addDays(30);
Use addDays() to Lastlogingdate and compare it with Today() to compare in If loops.
if(LLD == tday)
            	{
Insert users to one list<users> in if loop and update isActive field to False and Update that after For loop **DONE** .

You can send email alerts as well for the user before deactivation.

This Functionallity is already acheived feel free to ask anything.

Thansk & Regards
HarshaSekhar.K
 
vishal yadav 78vishal yadav 78
Hi Anas,

Thanks,

But i want to implement accourding my requiremnet. 
like how to set configration for that custom setting and profile.

select field from user where last loginedate < custom setting and profile in (custom settings)) and username not in (custom setting)

select field from user where last logindate is null and profile in (custom setting) and username not in (custom setting) and created date
vishal yadav 78vishal yadav 78
Dear Harsha, Please let me know how implement by code and configuration because I’m using first time batch class. What is the complete process please of batch class schedule explain See also my scenario also select field from user where last loginedate < custom setting and profile in (custom settings)) and username not in (custom setting) select field from user where last logindate is null and profile in (custom setting) and username not in (custom setting) and created date
vishal yadav 78vishal yadav 78
Pls hel meout anyone or suggestm me .
vishal yadav 78vishal yadav 78
I make a logic but my code is not able to find solution. 
Can any one check it. please. How to test using custiom setting .

global class DeactivateUsers implements Database.Batchable<SObject>
{
    
      //dateTime dt = date.today()-30;
    public String query = 'SELECT Name,Last_Deactivated__c, LastLoginDate,User License, Id From User WHERE IsActive = true AND LastLoginDate < +dt and User License = Salesforce,Partner Community and profile<>"CS CAMS","RCU Reporting User","PL Senior Manager","BILPL Regional Officer","BILPL Sales Coordinator","BILPL Sales Officer","BILPL Telecaller","CD Regional Officer","CS Branch","CS Email","CS Inbound","CS Manager","CS Operations","Credit Verifier","Cross Sell Telecaller","Cross Sell Telecaller Manager","PL Sales Manager","Reporting User","Risk Verifier","Sales Coordinator","Senior Manager","TW Regional Officer","TW Sales Coordinator","TW Sales Officer","UC Regional Officer","UC Sales Coordinator","Underwriter","Verification Coordinator","Open Market Telecallers","Customer Retention Officer","Partner Community User","Integration","Marketing User","Read Only","Solution Manager" ';
    
    //initate batch jobs
    global Database.querylocator start(Database.BatchableContext bc)
    {
        for(User u:[Select id,LastLoginDate,Createddate from user where isActive=true and ((LastLoginDate=null and Createddate<=:DATE.TODAY()-5) OR (LastLoginDate<=:DATE.TODAY()-30)) order by createddate desc  limit 1000]){
            system.debug('---->'+u);
    }
       return Database.getQueryLocator(query);
    }
    //batch apex execution
    global void execute(Database.BatchableContext bc,List<User> userss)
    {
        List<User> userList = new List<User>();
        
        for(User s:userss)
        {
            User u =(user)s;
            userList.add(u);
        }
        
        if(userList.size() > 0)
        {
            for(User usr : userList)
            {
                usr.isActive = false;
            }
        }
        update userList;
    }
    //finish batch jobs
    global void finish(Database.BatchableContext bc)
    {
        AsyncApexJob a = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, CreatedBy.Email
                          FROM AsyncApexJob 
                          WHERE Id = :BC.getJobId()];

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('Apex Job Status: ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
   
    
    
    }
}
vishal yadav 78vishal yadav 78
Hi Folk,


Initially i developed the some code but not able to implement .please any one can help me out.

global class DeactivateUserBatch implements Database.Batchable < sObject > {
global String query = '';
global List < String > profiles;
 
global DeactivateUserBatch() {
  Sring profiles = object__c.getInsance('Custom Settings');
  Sring userExc = object__c.getInsance('Custom Setting1');
  query = 'SELECT Id, name, isActive, LastLoginDate FROM User WHERE Active__c = True and Profile.Name in :profiles and username not in :userExc';
}
 
//initate batch jobs
global Database.QueryLocator start(Database.BatchableContext BC) {
  return Database.getQueryLocator(query);
}
 
 
//batch apex execution
global void execute(Database.BatchableContext BC, List < sObject > scope) {
 
  User userObj = (User) scope[0];
  deactivateRecord(userObj.Id);
}
 
//finish batch jobs
global void finish(Database.BatchableContext BC) {
  Object o = Database.query(query);
}
 
global static void start() {
  Database.executeBatch(new DeactivateUserBatch(), 1);
}
 
public static void deactivateRecord(String dUserId)
 {
 
  List < User > usersWoEscPoint = new List < User > ();
  List < User > usersWoCaseEscPoint = new List < User > ();
  List < User > usersWoManager = new List < User > ();
  List < User > usersToBeUpdated = new List < User > ();
  Map < Id, List < User >> escalationPointUserMap = new Map < Id, List < User >> ();
  Map < Id, List < User >> caseEscalationPointUserMap = new Map < Id, List < User >> ();
  Map < Id, List < User >> managerUserMap = new Map < Id, List < User >> ();
  Map < Id, List < User >> managerUserMaps = new Map < Id, List < User >> ();
  String dateFilter = getInsance('Custom Setting');
  deactivatedate = System.today - (:dateFilter)
  Map < Id, User > allUsers = new Map < Id, User > ([select Id, username, IsActive from User where isActive = true and LastLoginDate <= :deactivatedate]);
  Map < Id, User > notLoginUser = new Map < Id, User > ([select Id, username, IsActive from User where isActive = true and LastLoginDate = null and createddate <= System.today()- 5 ]);
 
  
  for (User currentUser: allUsers.values()) {
   if (managerUserMap.get(Manager) == null) {
    managerUserMap.put(currentUser.Manager, new List < User >
                {
     currentUser
    });
   }
   else {
    managerUserMap.get(currentUser.Manager).add(currentUser);
  
  }
  for (User currentUsers: notLoginUser.values()) {
   if (managerUserMaps.get(Manager) == null) {
    managerUserMap.put(currentUsers.Manager, new List < User >
                {
     currentUser
    });
   }
   else {
    managerUserMaps.get(currentUsers.Manager).add(currentUser);
  
  }
                String profiles = object__c.getInsance('Custom Settings');
 
  List < User > allDummyUsers = [select Id, isActive, Unsername, isActive from User where Id =: dUserId];
 
  for (User currentDummy: allDummyUsers)
  {
  
   User tempUser = allUsers.get(currentDummy.Id);
   tempUser.IsActive = currentDummy.isActive;
  
   if (currentDummy.isActive == false) {
    if (managerUserMap.get(tempUser.Id) != null)
     usersWoManager.addAll(managerUserMap.get(tempUser.Id));
   }
   usersToBeUpdated.add(tempUser);
  }
  update usersToBeUpdated;
  system.debug(JSON.serializePretty(usersToBeUpdated));
}
}
 
lakshminarayana reddylakshminarayana reddy
can you write the test class for the above khan anas code..