• Janice Mackedon
  • NEWBIE
  • 10 Points
  • Member since 2020

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 1
    Replies
Hello,
We have an Apex that was built by a priavte consultant back on November 2020 that would update the Owner Field on a Custom Object when their related Approval flow is reassigned to someone else. It appeared to be working fine and on January 13th 2020 we rolled the training on the Custom Object and I started reciving these error emails that same day and have every day since.
Error email body recieved daily:
Apex script unhandled exception by user/organization: 0051N000005gh9F/00D1N000002Jn2i

Failed to process batch for class 'SyncOwnerNameWithApproverBatch' for job id '7073l0000EQiAzS'

caused by: System.NullPointerException: Attempt to de-reference a null object


SF Support pointed me to this knowledge article but since I am and Admin and not a developer, I don't know what that all means or how the code would need to be modified. Also the Code Coverage is showing 0% (0/26) and I was told it has to be above 70%.
Knowledge Article: https://help.salesforce.com/articleView?id=000327918&type=1&mode=1

Below is what is in the Apex Code and I am hoping you all can provide some feedback on what needs to be modified as the Develpoer we used has told me we would have to pay him at this point to figure what the issue is and I don't want to go to my manager without any research of my own if we do need to pay someone again to fix this.

Apex Class Body:
/***************************************************************************************************************
* @author: AutomationChampion
* @Description: Batch Job to Sync Bid Approval Owner to be same as the Approver of the Approval Process
* @LastModifiedBy: Automation Champion
* @version 1.0
*
* Version History
* -------------------------------------------------------------------------------------------------------------
* Version  | Date      | Name      | Details of Change
* -------------------------------------------------------------------------------------------------------------
* 1.0.0    | 24-Nov-2020  | AChamp    | Created
* *************************************************************************************************************/

global class SyncOwnerNameWithApproverBatch implements Database.Batchable<sObject> {
    
    //Variable to hold the Object Prefix of the Bid Approval Object.
    global String keyPrefix = '';
    
    /*************************************************************************************
     * @author: AutomationChampion
     * @Description: Constructor to set the Object Prefix from Scheduleable class
     * @return: void
     * 
     * Change History
     * -----------------------------------------------------------------------------------
     * Date      | Name      | Details of Change
     * -----------------------------------------------------------------------------------
     * 24-Nov-2020  | AChamp    | Created
     * ***********************************************************************************/
    global SyncOwnerNameWithApproverBatch(String keyPrefix) {
        this.keyPrefix = keyPrefix;
        System.debug('@@ KeyPrefix from Scheduler @@ ' + keyPrefix);
    }
    
    /*************************************************************************************
     * @author: AutomationChampion
     * @Description: Start Method of the batch Class
     * @return: QueryLocator
     * 
     * Change History
     * -----------------------------------------------------------------------------------
     * Date      | Name      | Details of Change
     * -----------------------------------------------------------------------------------
     * 24-Nov-2020  | AChamp    | Created
     * ***********************************************************************************/
    global Database.QueryLocator start(Database.BatchableContext bc) {
       String objStartId = '';
       String query = 'SELECT Id, ProcessInstanceId, ProcessInstance.TargetObjectId, Actor.Name FROM ProcessInstanceWorkItem WHERE ProcessInstance.SystemModStamp > = LAST_N_DAYS:1';

        if(String.isNotBlank(keyPrefix)) {
            objStartId = keyPrefix + '000000000000';
            
            query += ' AND ProcessInstance.TargetObjectId > \'' + objStartId + '\'';
        }
        System.debug('@@ Final Query @@ ' + query);
        return Database.getQueryLocator(query);
    }
    
    /*************************************************************************************
     * @author: AutomationChampion
     * @Description: Execute Method to process the logic to identify which Bid Record 
     * Owners should be updated based on the approval process owners
     * @return: void
     * 
     * Change History
     * -----------------------------------------------------------------------------------
     * Date      | Name      | Details of Change
     * -----------------------------------------------------------------------------------
     * 24-Nov-2020  | AChamp    | Created
     * ***********************************************************************************/
    global void execute(Database.BatchableContext bc, list<sObject> scope) {
        
        //Collect the recordIds in a collection
        Set<Id> recordIds = new Set<Id>();
        
        //List to update the OwnerId
        List<BID_Approval__c> lstUpdateBidApproval = new List<BID_Approval__c>();
        
        //Loop through the records to get the RecordId and ApprovalProcess Ids
        for(sObject record :scope) {
            ProcessInstanceWorkItem approvalWorkItem = (ProcessInstanceWorkItem)record;
            recordIds.add(approvalWorkItem.ProcessInstance.TargetObjectId);
        }
        
        
        //Query the BID APPROVALS object 
        Map<Id, BID_Approval__c> mapBidApproval = new Map<Id, BID_Approval__c>([SELECT Id, OwnerId, Owner.Name FROM BID_Approval__c WHERE Id IN :recordIds]);

        for(sObject record :scope) {
             ProcessInstanceWorkItem approvalWorkItem = (ProcessInstanceWorkItem)record;
            
            //Get the Bid Approval record from the MAP 
            BID_Approval__c objBidApproval = mapBidApproval.get(approvalWorkItem.ProcessInstance.TargetObjectId);
            if(objBidApproval.OwnerId <> approvalWorkItem.ActorId) {
                //Assign the Approval Process owner to the ownerid in bid approval record
                objBidApproval.OwnerId = approvalWorkItem.ActorId;
                lstUpdateBidApproval.add(objBidApproval);
            }
            
        }
        
        //Update the Bid Approval Records
        if(lstUpdateBidApproval != null && lstUpdateBidApproval.size() > 0) {
             System.debug('@@ lstUpdateBidApproval @@ ' + lstUpdateBidApproval);
            update lstUpdateBidApproval;
        }
    }
    
    /*************************************************************************************
     * @author: AutomationChampion
     * @Description: Finish Method of the Batch Class
     * @return: void
     * 
     * Change History
     * -----------------------------------------------------------------------------------
     * Date      | Name      | Details of Change
     * -----------------------------------------------------------------------------------
     * 24-Nov-2020  | AChamp    | Created
     * ***********************************************************************************/
    global void finish (Database.BatchableContext bc) {
        
    }
}

 
Our org has decided to use approval processes on the opportunity records and I have found that in testing that when a user hits the sumbit for approval button there is nothing that pops up to inform them what process they are submitting. So when you have several procceses is there a way to code to get a pop up that tells them you are submitting approval process A or B before they hit send?
I have a new laptop and my connection to Salesforce in Excel Power Query is now giving me an error. I also tried recreating the query and I still get the same error. Can anyone advise what would be causing this "DataSource.Error: The request was aborted: Could not create SSL/TLS secure channel.
Details:
https://6.my.salesforce.com/services/data/v29.0/sobjects"
Our org has decided to use approval processes on the opportunity records and I have found that in testing that when a user hits the sumbit for approval button there is nothing that pops up to inform them what process they are submitting. So when you have several procceses is there a way to code to get a pop up that tells them you are submitting approval process A or B before they hit send?