• CTIT Insulation
  • NEWBIE
  • 10 Points
  • Member since 2016

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 2
    Replies
Hi All. I am trying to promote an Apex trigger, an Apex class, and an Apex test class. All work in sandbox environment, but when I try to validate during promotion to production, I get "Attempt to de-reference a null object" error, which points to the last line of code in the Apex class, which contains only the closing bracket. This was copied from a similar set of classes on another object, which is in production with no issues.

Here is the trigger:
trigger Contract_Triggers on Contract (after update) { //only runs after update

    set<id> ContractIds = new set<id>();

    if(trigger.isafter){
        if(trigger.isupdate){
            for(Contract c:trigger.new){
                if(c.Copy_Approval_Comments__c == true){
                    ContractIds.add(c.id);
                }
            }
        }
    }
    
    //calls @future class to ensure order of operation.
    if(ContractIds.size() > 0) {
        Contract_Approval_Comment_Handler.updateContractComment(ContractIds);
    }
        
}


Here is the Apex class:
public class Contract_Approval_Comment_Handler {
    @future
    public static void updateContractComment(set<id> cList){

        List<Contract> Contracts = [Select c.Id, c.Copy_Approval_Comments__c, c.Approval_Comments__c, (Select ActorId, Comments, CreatedDate From ProcessSteps order by CreatedDate) 
                             From 
                                 Contract c
                             where 
                                 c.Copy_Approval_Comments__c = True AND 
                                 c.id IN: cList];
            
        List<Contract> ContractsToUpdate = new List<Contract>(); //stores records to be updated
        
        //creates map of users that are active and non portal users 
        Map<ID, User> uMap = new Map<ID, User>([SELECT Id, Name FROM User WHERE IsActive =: true]);
        system.debug('User Map >>>>> ' + uMap);
        
        System.debug('******************************************** Contract = ' + Contracts);
        System.debug('******************************************** Size of Contract = ' + Contracts.size());
        
        if (Contracts.size()>0){
            for(Contract con: Contracts){
                if(con.ProcessSteps.size() >0){  
                    con.Approval_Comments__c = '';
                    for (ProcessInstanceHistory ps : con.ProcessSteps){
                        if (ps.Comments != null){
                            string username = uMap.get(ps.ActorId).name;   
                            con.Approval_Comments__c += '\n' + username + ': ' + ps.Comments;          
                             System.debug('*********************************************** Comments copied:' + ps.comments);
                         }
                     }
                     con.Copy_Approval_Comments__c =false;
                     ContractsToUpdate.add(con);
                 }
             }
        }
        
        if( ContractsToUpdate.size()> 0 ){
        
            Database.SaveResult[] srList = Database.update(ContractsToUpdate, false);
        
            // Iterate through each returned result
            for (Database.SaveResult sr : srList) {
                if (sr.isSuccess()) {
                    // Operation was successful, so get the ID of the record that was processed
                    System.debug('Successfully updated record 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());
                    }
                }
            }
        }
    }    
}

And here is the test class:
@isTest(SeeAllData=True)
public class Contract_Approval_Comment_HandlerTest {
  static testMethod void run()

  {  List<Contract> Contracts = [Select c.Id, c.Copy_Approval_Comments__c From Contract c where c.Status = 'Activated' and c.Multiple_Trailers_at_this_location__c = False limit 100];
            
        List<Contract> ContractsToUpdate = new List<Contract>(); //stores records to be updated
        set<id> ContractIds = new set<id>();
             
        if (Contracts.size()>0){
            for(Contract con: Contracts){
                    con.Copy_Approval_Comments__c = True;
                    ContractsToUpdate.add(con);
                    ContractIDs.add(con.Id);
                }
             }
      
       if( ContractsToUpdate.size()> 0 ){
            Database.SaveResult[] srList = Database.update(ContractsToUpdate);
         }
   
   
       Test.startTest();     
            Contract_Approval_Comment_Handler.UpdateContractComment(ContractIds);    
       Test.stopTest();   
  }  
}
Any help will be greatly appreciated.

Thanks,
Stave A.
 
Hi All. I am trying to promote an Apex trigger, an Apex class, and an Apex test class. All work in sandbox environment, but when I try to validate during promotion to production, I get "Attempt to de-reference a null object" error, which points to the last line of code in the Apex class, which contains only the closing bracket. This was copied from a similar set of classes on another object, which is in production with no issues.

Here is the trigger:
trigger Contract_Triggers on Contract (after update) { //only runs after update

    set<id> ContractIds = new set<id>();

    if(trigger.isafter){
        if(trigger.isupdate){
            for(Contract c:trigger.new){
                if(c.Copy_Approval_Comments__c == true){
                    ContractIds.add(c.id);
                }
            }
        }
    }
    
    //calls @future class to ensure order of operation.
    if(ContractIds.size() > 0) {
        Contract_Approval_Comment_Handler.updateContractComment(ContractIds);
    }
        
}


Here is the Apex class:
public class Contract_Approval_Comment_Handler {
    @future
    public static void updateContractComment(set<id> cList){

        List<Contract> Contracts = [Select c.Id, c.Copy_Approval_Comments__c, c.Approval_Comments__c, (Select ActorId, Comments, CreatedDate From ProcessSteps order by CreatedDate) 
                             From 
                                 Contract c
                             where 
                                 c.Copy_Approval_Comments__c = True AND 
                                 c.id IN: cList];
            
        List<Contract> ContractsToUpdate = new List<Contract>(); //stores records to be updated
        
        //creates map of users that are active and non portal users 
        Map<ID, User> uMap = new Map<ID, User>([SELECT Id, Name FROM User WHERE IsActive =: true]);
        system.debug('User Map >>>>> ' + uMap);
        
        System.debug('******************************************** Contract = ' + Contracts);
        System.debug('******************************************** Size of Contract = ' + Contracts.size());
        
        if (Contracts.size()>0){
            for(Contract con: Contracts){
                if(con.ProcessSteps.size() >0){  
                    con.Approval_Comments__c = '';
                    for (ProcessInstanceHistory ps : con.ProcessSteps){
                        if (ps.Comments != null){
                            string username = uMap.get(ps.ActorId).name;   
                            con.Approval_Comments__c += '\n' + username + ': ' + ps.Comments;          
                             System.debug('*********************************************** Comments copied:' + ps.comments);
                         }
                     }
                     con.Copy_Approval_Comments__c =false;
                     ContractsToUpdate.add(con);
                 }
             }
        }
        
        if( ContractsToUpdate.size()> 0 ){
        
            Database.SaveResult[] srList = Database.update(ContractsToUpdate, false);
        
            // Iterate through each returned result
            for (Database.SaveResult sr : srList) {
                if (sr.isSuccess()) {
                    // Operation was successful, so get the ID of the record that was processed
                    System.debug('Successfully updated record 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());
                    }
                }
            }
        }
    }    
}

And here is the test class:
@isTest(SeeAllData=True)
public class Contract_Approval_Comment_HandlerTest {
  static testMethod void run()

  {  List<Contract> Contracts = [Select c.Id, c.Copy_Approval_Comments__c From Contract c where c.Status = 'Activated' and c.Multiple_Trailers_at_this_location__c = False limit 100];
            
        List<Contract> ContractsToUpdate = new List<Contract>(); //stores records to be updated
        set<id> ContractIds = new set<id>();
             
        if (Contracts.size()>0){
            for(Contract con: Contracts){
                    con.Copy_Approval_Comments__c = True;
                    ContractsToUpdate.add(con);
                    ContractIDs.add(con.Id);
                }
             }
      
       if( ContractsToUpdate.size()> 0 ){
            Database.SaveResult[] srList = Database.update(ContractsToUpdate);
         }
   
   
       Test.startTest();     
            Contract_Approval_Comment_Handler.UpdateContractComment(ContractIds);    
       Test.stopTest();   
  }  
}
Any help will be greatly appreciated.

Thanks,
Stave A.