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
AzusfdcAzusfdc 

Here Whatever the data is coming in List<Sobject> with condition like if account object selected then need to get the data and inserted in .csv file could any body help ?

My Requirement is I want to delete the records in account and case object before that need to take backup should be inserted in document with .csv file based on lastmodifieddate and createddate before's last 10 months data i am deleting below is code i am written one is batch apex and normal class?
Batch Apex:
/*
  * @description   Batch class for implementing the Data Retention Rule for record deletion based on the values populated in the DRR record
  */
global class BATCH_DataRetention implements Database.Batchable<SObject> {
    
    private static final String COMP = 'Completed';
    private String queryString = null;
    private String queryParentString = null;
    private Boolean callScheduler = false;
    private List<Data_Retention_Rule__c> drrListChildRules = new List<Data_Retention_Rule__c>();
    //Keep a reference to the Data Retention Batch record that is being used to run this batch
    private DataRetentionBatch__c drbObject = new DataRetentionBatch__c();
    
    global BATCH_DataRetention(String query, List<Data_Retention_Rule__c> listChildRules, DataRetentionBatch__c drbObj, Boolean callSchedulerClass) {
        
        drrListChildRules = listChildRules;
        
        if(drrListChildRules != null && !drrListChildRules.isEmpty()) {
            queryParentString = query;
            queryString = 'SELECT Id ' + query.substring(query.lastIndexOf('FROM'),query.length());
            
            system.debug('query string-->'+queryString+'--main query--'+queryParentString);
        }
        else {
            queryString = query;
        }
        
        drbObject = drbObj;
        callScheduler = callSchedulerClass;
    }
    
    /**
      * @description       This method queries the soql query and passes the List of records obtained to the execute method.
      * @param             Database.BatchableContext object
      * @return            Database.QueryLocator
      * @throws            NA
      */
    global Database.QueryLocator start(Database.BatchableContext ctx) {
        return Database.getQueryLocator(queryString + ' LIMIT 50000000');
    }
    
    /**
      * @description       Method executes the query and return the QueryLocator Object
      * @param             Database.BatchableContext object
      * @param             scope
      * @return            NA
      * @throws            NA
      */
    global void execute(Database.BatchableContext ctx, List<sObject> scope) {
        List<sObject> sObjectList = new List<sObject>();
        List<sObject> sObjectParentList = new List<sObject>();
        List<Case> cs = new List<Case>();
        Document d = new Document();
        string header = ' \' '+queryParentString.substring(queryParentString.lastIndexOf('FROM')) + ' \' ';
        string finalstr = header;
        system.debug('scope size--->'+scope.size());
        // for each child rule query, check the related records for each item in the batch of parent records,
        // if the parent qualifies for archival/deletion, take the action immediately
        if(drrListChildRules != null && !drrListChildRules.isEmpty()) {
            sObjectParentList = Database.query(queryParentString + ' AND Id IN: scope LIMIT ' + scope.size());
            sObjectList = DataRetentionQueryBuilder.qualifyRecordsToBeDeleted(sObjectParentList,drrListChildRules);
             Boolean result = queryParentString.contains('Account');
              if(result == true){
              // acc.add(sObjectList);
              }
              else{
              // cs.add((ID)sObjectParentList.get('Case'));
              }
        }
        else {
            sObjectList = DataRetentionQueryBuilder.qualifyRecordsToBeDeleted(scope,drrListChildRules);
        }
        
        // delete the parent records that qualify for archival/deletion
        if(sObjectList != null && !sObjectList.isEmpty()) {
            Database.DeleteResult[] drList = Database.delete(sObjectList, false);
        }
    }
    
    /**
      * @description       Finish method to update the Data Retention Batch record with the 
      * @param             Database.BatchableContext object
      * @return            void
      * @throws            NA
      */
    global void finish(Database.BatchableContext ctx) {
        try {
            AsyncApexJob asyJob = [SELECT Status FROM AsyncApexJob WHERE Id =: ctx.getJobId() LIMIT 1];
            
            // if job finished successfully update the drb record status to completed
            if(COMP.equalsIgnoreCase(asyJob.Status)) {
                drbObject.Status__c = COMP;
            }
            
            // update the try count for tracking purpose
            drbObject.Try_Count__c += 1;
            update drbObject;
            
            if(callScheduler) {
                //Build the system time of now + 30 minutes to schedule the batch apex again
                Datetime sysTime = System.now();
                
                // to be able to catch Async Exception in test class
                if(!Test.isRunningTest()) { sysTime = sysTime.addMinutes(30); }
                
                String chron_exp = '' + sysTime.second() + ' ' + sysTime.minute() + ' ' + sysTime.hour() + ' ' + sysTime.day() + ' ' + sysTime.month() + ' ? ' + sysTime.year();
                SCH_DataRetention schDR = new SCH_DataRetention();
                //Schedule the next job, and give it the system time so name is unique
                System.schedule('scheduleDataRetentionRuleJobs' + sysTime.getTime(),chron_exp,schDR);
            }
        }
        // since it is not possible to catch a query exception in the test class, however, the system might throw an exception,
        // hence adding a generic exception block
        catch (Exception e) { /* Log the exception in a custom object */ }
    }
}
 
/**
  * @description   This class acts as a helper class for the scheduler SCH_DateRetention and batch BATCH_DataRetention
  */
public with sharing class DataRetentionQueryBuilder {
    
    /**
      * @name             populateMapParentChildListRules
      * @description      Method is called to populate a map with the parent rule as key and list of child rules as values
      * @param            Set<String>
      * @return           Map<sObject,List<sObject>>
      * @throws           NA
      */
    public static Map<Data_Retention_Rule__c,List<Data_Retention_Rule__c>> populateMapParentChildListRules(Set<String> drrSetParentIds) {
    
        Map<Data_Retention_Rule__c,List<Data_Retention_Rule__c>> mapParentChildListRules = new Map<Data_Retention_Rule__c,List<Data_Retention_Rule__c>>();
        
        try {
            List<Data_Retention_Rule__c> parentDrrList = new List<Data_Retention_Rule__c>();
            // get the list of parent records from the set of ids passed as parameters
            parentDrrList = [SELECT Key_Field__c, Months__c, Object__c, Record_Type__c
                             FROM Data_Retention_Rule__c WHERE Id IN: drrSetParentIds AND Parent_Data_Retention_Rule__c = null
                             LIMIT: Limits.getLimitQueryRows() - Limits.getQueryRows()];
            
            if(!parentDrrList.isEmpty()) {
                // prepare a map of parent records and list of child records
                for(Data_Retention_Rule__c drrChild: [SELECT Key_Field__c, Months__c, Record_Type__c,
                                                      Parent_Data_Retention_Rule__c, Child_Relationship_Name__c
                                                      FROM Data_Retention_Rule__c WHERE Parent_Data_Retention_Rule__c != null
                                                      AND Parent_Data_Retention_Rule__c IN: drrSetParentIds
                                                      LIMIT: Limits.getLimitQueryRows() - Limits.getQueryRows()]) {
                    for(Data_Retention_Rule__c drrParent: parentDrrList) {   
                        if(String.valueOf(drrParent.id).equals(String.valueOf(drrChild.Parent_Data_Retention_Rule__c))) {
                            if(mapParentChildListRules.containsKey(drrParent)) {
                                List<Data_Retention_Rule__c> listChildRules = mapParentChildListRules.get(drrParent);
                                listChildRules.add(drrChild);
                                mapParentChildListRules.put(drrParent,listChildRules);
                              system.debug('>>>>listChildRules>>>>>>>>>>>>>>>>>'+listChildRules);
                            system.debug('>>>>drrParent>>>>>>>>>>>>>>>>>'+drrparent);   
                            
                            }
                                                   
                            
                            else{
                                mapParentChildListRules.put(drrParent,new List<Data_Retention_Rule__c>{drrChild});
                            }
                            break;
                        }
                    }
                }
                
                // for parent rules that do not have any child rules associated to them
                for(Data_Retention_Rule__c drrParent: parentDrrList) {
                    if(!mapParentChildListRules.containsKey(drrParent)) {
                        mapParentChildListRules.put(drrParent,null);
                    }
                }
            }
        }
        catch (QueryException qExcp) { /* Log exception to a custom object */ }
        
        return mapParentChildListRules;
    }
    
    
    
    /**
      * @name             buildFinalQueryFromRule
      * @description      Method is called to build a final query which will be passed to the Database.queryLocator
      *                   to retrieve the list of records to be deleted
      * @param            sObject record
      * @param            List<sObject> records
      * @return           String (final query String)
      * @throws           NA
      */
    public static String buildFinalQueryFromRule(Data_Retention_Rule__c parentRule, List<Data_Retention_Rule__c> listChildRules) {
        String finalQuery = null;
        if(parentRule.Object__c == 'Account'){
        finalQuery = 'SELECT Id,Name,Industry,Phone,AccountSource';
        system.debug('======================='+finalQuery);
        }
        else{         
        finalQuery = 'SELECT Id,type,Status,Priority,Origin';
        system.debug('======================='+finalQuery);
        }
        
        // if any child record exists, add the inner query string as part of the final query string being built
        if(listChildRules != null && !listChildRules.isEmpty()) {
            for(Data_Retention_Rule__c childRule: listChildRules) {
                finalQuery += buildQueryFromChildRule(childRule);
            }
        }
        
        finalQuery += ' FROM ' + parentRule.Object__c + ' WHERE ';
        
        if(String.isNotBlank(parentRule.Record_Type__c)) {
            finalQuery += 'RecordType.Name = \'' + parentRule.Record_Type__c + '\' AND ';
        }
        
        finalQuery += parentRule.Key_Field__c + ' < ' + writeDate(parentRule.Months__c);
        
        return finalQuery;
    }
    
    /**
      * @name             buildQueryFromChildRule
      * @description      Method is called to form a query string based on the values input in the Data_Retention_Rule record
      * @param            sObject - Data_Retention_Rule__c
      * @return           String
      * @throws           NA
      */
    private static String buildQueryFromChildRule(Data_Retention_Rule__c rule) {
        String query = null;
        
        query = ', (SELECT Id,type,Status,Priority,Origin FROM ' + rule.Child_Relationship_Name__c + ' WHERE ';
        
        if(String.isNotBlank(rule.Record_Type__c)) {
            query += 'RecordType.Name = \'' + rule.Record_Type__c + '\' AND ';
        }
        
        query += rule.Key_Field__c + ' > ' + writeDate(rule.Months__c) + ')';
        
        return query;
    }
    
    /**
      * @name             qualifyRecordsToBeDeleted
      * @description      Method is called to check if the list of sObjects qualify the criteria for archival/deletion
      * @param            List<sObject>
      * @param            sObject - Data_Retention_Rule__c
      * @param            List<sObject> - List<Data_Retention_Rule__c>
      * @return           List<sObject>
      * @throws           NA
      */
    public static List<sObject> qualifyRecordsToBeDeleted(List<sObject> sObjectList, List<Data_Retention_Rule__c> listChildRules) {
        
        // create a set of sObjects and populate it with the list of parent sObjects
        Set<sObject> sObjectSet = new Set<sObject>();
        sObjectSet.addAll(sObjectList);
        
        // for each child rule query, check the related records for each item in the batch of parent records,
        // if the parent qualifies for archival/deletion, take the action immediately
        if(listChildRules != null && !listChildRules.isEmpty()) {
            for(sObject sObj: sObjectSet) {
                for(Data_Retention_Rule__c drr: listChildRules) {
                    // check for each list of child records
                    // if any list of child records is not null, the parent does not qualify to be deleted
                    if(sObj.getSObjects(drr.Child_Relationship_Name__c) != null && sObj.getSObjects(drr.Child_Relationship_Name__c).size() > 0) {
                        // remove the parent record from the set
                        sObjectSet.remove(sObj);
                        // move on to next parent record
                        break;
                    }
                }
            }
        }
        // clear the sObject List
        sObjectList.clear();
        // add the values that still remain in the sObject set to the sObject list so that these can be passed back for deletion
        sObjectList.addAll(sObjectSet);
        
        return sObjectList;
    }
    
    /**
      * @name             writeDate
      * @description      Method returns a date time value of the present date minus the number of months input in the Data_Retention_Rule record
      * @param            Decimal
      * @return           DateTime
      * @throws           NA
      */
    private static String writeDate(Decimal ruleMonths) {
        String comparisonDt = String.valueOf(DateTime.now().addMonths(-1*(Integer)ruleMonths));
        
        String finalCompareDate = comparisonDt.split(' ')[0] + 'T' + comparisonDt.split(' ')[1] + '.000Z';
        
        return finalCompareDate;
    }
}
Object Exp