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
Muna Jamous5Muna Jamous5 

batchable

Hi, I am new in Apex Batch I wrote an Apex class that works fine for small data, but when I execute it in large data set I receive CPU limit, I read about Apex batch and it could solve my problem, but I have difficult time inc converting my class to apex batchable class. below is my apex class Any help is highly appreciated. 
public class EquipmentBOQProcessController {
    
    @AuraEnabled
    public static void calculateBOQ(String hospitalName){
        
        String OEMHospital;
        if(hospitalName.equalsIgnoreCase('H1')) {
            OEMHospital = 'First One';
        }else if (hospitalName.equalsIgnoreCase('H2')) {
            OEMHospital = 'Second one';
        }   
        id BOQRecordType = [SELECT id FROM RecordType where developerName=:hospitalName and sobjectType='Equipment_BOQ__c'].id;
        List<Equipment_BOQ__c> listToDelete = new List<Equipment_BOQ__c>([SELECT id from Equipment_BOQ__c where RecordType.id =:BOQRecordType]); 
        
        // Step - 1 : Delete all records related to that Hospital
        If (listToDelete.size() > 0) {
           Database.DeleteResult[]  result = deletePreviousRecords(listToDelete);
        }
        
        // Step - 2: Insert New Records         
        // New List
        List<Equipment_in_Room__c> inRoomNew = new List<Equipment_in_Room__c>([ Select Plan_Id__c, Hospital_Room__c , Package_No__c ,  Legacy__c, Status__c
                                                                            from Equipment_in_Room__c where Hospital_name__c=: OEMHospital AND Status__c = 'NEW']);  		
        //If no Equipment in the hospital Rooms                                                                                                                          
        if (inRoomNew.size() > 0) {
            List<AggregateResult> inRoomNewTotals = [Select  Plan_Id__c, Sum(Total_Qty__c)TQ, Sum(Cost_New__c)CN, Sum(Total_Budget_Price__c)TPP, Sum(Total_Cost_Including_Contingency__c)TCIC
                                                      , Sum(Total_Legacy_Move_Total_Contingency_New__c)TLMTC from Equipment_in_Room__c  where Hospital_name__c=: OEMHospital and Status__c = 'NEW'  
                                                      Group By Plan_Id__c];
            
            Set<Id> hrNewids = new Set<id>();
            
            for (integer i=0 ; i < inRoomNew.size() ; i++ ) {
                hrNewids.add(inRoomNew[i].Hospital_Room__c);
            }
			Map<Id,Hospital_Room_No__c> hospitalRoomsDept = new Map<Id,Hospital_Room_No__c>([Select Department__c from Hospital_Room_No__c where id in :hrNewids ]);
        	
            
        	insertEquipmentBOQ(BOQRecordType, inRoomNew , inRoomNewTotals , hospitalRoomsDept);    
        }               
	}  
	
     Private static void insertEquipmentBOQ(id hospitalName, List<Equipment_in_Room__c> inRoom  , List<AggregateResult> inRoomTotals, Map<Id,Hospital_Room_No__c> hospitalRoomsDept ){
        List<Equipment_BOQ__c> AllBOQRec = new List<Equipment_BOQ__c>();
       
         id planId;
         
         for(AggregateResult agr :inRoomTotals){
			Equipment_BOQ__c BOQRec = new Equipment_BOQ__c();
            planId =  (Id)agr.get('Plan_Id__c');
            BOQRec.RecordTypeId = hospitalName;
			BOQRec.Equipment_Detail__c = planId;
            BOQRec.Total_Qty__c = (Double)agr.get('TQ');
            BOQRec.Cost_New__c = (Decimal)agr.get('CN');
            BOQRec.Total_Budget_Price__c = (Decimal)agr.get('TPP');
            BOQRec.Total_Cost_Including_Contingency__c = (Decimal)agr.get('TCIC');
            BOQRec.legacy_Total_Move_Total_Contingency_New__c = (Decimal)agr.get('TLMTC');
            BOQRec.Department__c = '';
             for (Equipment_in_Room__c er :inRoom ) {
                 if (er.Plan_Id__c == planId) {
                     BOQRec.Legacy__c = er.Legacy__c==true ? 'YES' : 'NO';
                     BOQRec.Inv_Stat__c = er.Status__c;
                     BOQRec.Package__c = er.Package_No__c;   
                     //collecting Departments
                     String roomDept= hospitalRoomsDept.get(er.Hospital_Room__c).Department__c;
                     if (BOQRec.Department__c.indexof(roomDept) == -1) {
           				BOQRec.Department__c = roomDept + ' , ' + BOQRec.Department__c ; 
       				 } 
                 }
             }            
            AllBOQRec.add(BOQRec);
        } 
   
         try { 
        	Database.SaveResult[] result = Database.insert(AllBOQRec, true);
            System.debug('All BOQ Records were inserted successfully');              
         } catch(DmlException e) {
            System.debug('BOQ Records were falied to insert'); 
         }
}
    
    private static Database.DeleteResult[] deletePreviousRecords(List<Equipment_BOQ__c> listToDelete ) {
        Database.DeleteResult[] deleteResult;
        try {
        	deleteResult = Database.delete(listToDelete, true);
            System.debug('Deleted ...!');
        } catch (DmlException e) {
            System.debug('Delete all BOQ ' + e.getMessage());
        }
        return deleteResult;
    }
     
}

 
Maharajan CMaharajan C
Hi Muna,

Try the below code : 

I thought you are hitting the CPU Limit Exception while your are using the for inside the for loop line 47 & 58 so use the Map Collection instead of that like below:

public class EquipmentBOQProcessController {
    
    @AuraEnabled
    public static void calculateBOQ(String hospitalName){
        
        String OEMHospital;
        if(hospitalName.equalsIgnoreCase('H1')) {
            OEMHospital = 'First One';
        }else if (hospitalName.equalsIgnoreCase('H2')) {
            OEMHospital = 'Second one';
        }   
        id BOQRecordType = [SELECT id FROM RecordType where developerName=:hospitalName and sobjectType='Equipment_BOQ__c'].id;
        List<Equipment_BOQ__c> listToDelete = new List<Equipment_BOQ__c>([SELECT id from Equipment_BOQ__c where RecordType.id =:BOQRecordType]); 
        
        // Step - 1 : Delete all records related to that Hospital
        If (listToDelete.size() > 0) {
           Database.DeleteResult[]  result = deletePreviousRecords(listToDelete);
        }
        
        // Step - 2: Insert New Records         
        // New List
        List<Equipment_in_Room__c> inRoomNew = new List<Equipment_in_Room__c>([ Select Plan_Id__c, Hospital_Room__c , Package_No__c ,  Legacy__c, Status__c
                                                                            from Equipment_in_Room__c where Hospital_name__c=: OEMHospital AND Status__c = 'NEW']);          
        
        Map<Id,Equipment_in_Room__c> inRoomNewMap = new Map<Id,Equipment_in_Room__c>();
        
        //If no Equipment in the hospital Rooms                                                                                                                          
        if (inRoomNew.size() > 0) {
            
            for(Equipment_in_Room__c EinRoom : inRoomNew)
            {
                    if(!inRoomNewMap.containskey(EinRoom.Plan_Id__c))
                        inRoomNewMap.put(EinRoom.Plan_Id__c,EinRoom);
            }
            
            List<AggregateResult> inRoomNewTotals = [Select  Plan_Id__c, Sum(Total_Qty__c)TQ, Sum(Cost_New__c)CN, Sum(Total_Budget_Price__c)TPP, Sum(Total_Cost_Including_Contingency__c)TCIC
                                                      , Sum(Total_Legacy_Move_Total_Contingency_New__c)TLMTC from Equipment_in_Room__c  where Hospital_name__c=: OEMHospital and Status__c = 'NEW'  
                                                      Group By Plan_Id__c];
            
            Set<Id> hrNewids = new Set<id>();
            
            for (integer i=0 ; i < inRoomNew.size() ; i++ ) {
                hrNewids.add(inRoomNew[i].Hospital_Room__c);
            }
            Map<Id,Hospital_Room_No__c> hospitalRoomsDept = new Map<Id,Hospital_Room_No__c>([Select Department__c from Hospital_Room_No__c where id in :hrNewids ]);
            
            
            insertEquipmentBOQ(BOQRecordType, inRoomNew , inRoomNewMap , inRoomNewTotals , hospitalRoomsDept);    
        }               
    }  
    
     Private static void insertEquipmentBOQ(id hospitalName, List<Equipment_in_Room__c> inRoom ,Map<Id,Equipment_in_Room__c> inRoomNewMap1 , List<AggregateResult> inRoomTotals, Map<Id,Hospital_Room_No__c> hospitalRoomsDept ){
        List<Equipment_BOQ__c> AllBOQRec = new List<Equipment_BOQ__c>();
       
         id planId;
         
         for(AggregateResult agr :inRoomTotals){
            Equipment_BOQ__c BOQRec = new Equipment_BOQ__c();
            planId =  (Id)agr.get('Plan_Id__c');
            BOQRec.RecordTypeId = hospitalName;
            BOQRec.Equipment_Detail__c = planId;
            BOQRec.Total_Qty__c = (Double)agr.get('TQ');
            BOQRec.Cost_New__c = (Decimal)agr.get('CN');
            BOQRec.Total_Budget_Price__c = (Decimal)agr.get('TPP');
            BOQRec.Total_Cost_Including_Contingency__c = (Decimal)agr.get('TCIC');
            BOQRec.legacy_Total_Move_Total_Contingency_New__c = (Decimal)agr.get('TLMTC');
            BOQRec.Department__c = '';
           /*  for (Equipment_in_Room__c er :inRoom ) {
                 if (er.Plan_Id__c == planId) {
                     BOQRec.Legacy__c = er.Legacy__c==true ? 'YES' : 'NO';
                     BOQRec.Inv_Stat__c = er.Status__c;
                     BOQRec.Package__c = er.Package_No__c;   
                     //collecting Departments
                     String roomDept= hospitalRoomsDept.get(er.Hospital_Room__c).Department__c;
                     if (BOQRec.Department__c.indexof(roomDept) == -1) {
                           BOQRec.Department__c = roomDept + ' , ' + BOQRec.Department__c ; 
                        } 
                 }
             }    */
            if(inRoomNewMap1.containskey(planId))
            {
                Equipment_in_Room__c er = inRoomNewMap1.get(planId);
                BOQRec.Legacy__c = er.Legacy__c==true ? 'YES' : 'NO';
                BOQRec.Inv_Stat__c = er.Status__c;
                BOQRec.Package__c = er.Package_No__c;   
                     //collecting Departments
                String roomDept= hospitalRoomsDept.get(er.Hospital_Room__c).Department__c;
                if (BOQRec.Department__c.indexof(roomDept) == -1) {
                   BOQRec.Department__c = roomDept + ' , ' + BOQRec.Department__c ; 
                   }   

            }
             
            AllBOQRec.add(BOQRec);
        } 
   
         try { 
            Database.SaveResult[] result = Database.insert(AllBOQRec, true);
            System.debug('All BOQ Records were inserted successfully');              
         } catch(DmlException e) {
            System.debug('BOQ Records were falied to insert'); 
         }
}
    
    private static Database.DeleteResult[] deletePreviousRecords(List<Equipment_BOQ__c> listToDelete ) {
        Database.DeleteResult[] deleteResult;
        try {
            deleteResult = Database.delete(listToDelete, true);
            System.debug('Deleted ...!');
        } catch (DmlException e) {
            System.debug('Delete all BOQ ' + e.getMessage());
        }
        return deleteResult;
    }
     
}

Can you please Let me know if it helps or not!!!

If it helps don't forget to mark this as a best answer!!!


Thanks,
Raj
Muna Jamous5Muna Jamous5
Hi Raj, Thank you for your reply. The solution you provided changes the business logic because the Map will only contain a unique Plan_id, however, the list could have multiple with the same plan id. So it did not solve my problem. Thanks Muna