Mass Approval using Lightning Web Component in Salesforce

Mass Approval using Lightning Web Component in Salesforce

Sample code:

Apex Class:

public class MassApprovalController {
    
    @AuraEnabled( cacheable = true )
    public static List < MassApprovalWrapper > fetchPendingApprovalRecords() {
        
        List < MassApprovalWrapper > listMAWs = new List < MassApprovalWrapper >();
        Set < Id > setRecordIds = new Set < Id >();
        
        List < ProcessInstanceWorkitem > listPIWs = [
            SELECT Id, ActorId, ProcessInstance.Status, ProcessInstance.TargetObjectId,
            ProcessInstance.TargetObject.Name, ProcessInstance.TargetObject.Type
            FROM ProcessInstanceWorkitem
            WHERE ActorId =: UserInfo.getUserId()
        ];
        
        for ( ProcessInstanceWorkitem objPIW : listPIWs ) {
            
            MassApprovalWrapper objMAW = new MassApprovalWrapper();
            objMAW.PIWId = objPIW.Id;
            objMAW.status = objPIW.ProcessInstance.Status;
            objMAW.objectRecordId = objPIW.ProcessInstance.TargetObjectId;
            objMAW.name = objPIW.ProcessInstance.TargetObject.Name;
            objMAW.objType = objPIW.ProcessInstance.TargetObject.Type;
            listMAWs.add( objMAW );
            
        }
        
        return listMAWs;
        
    }
    
    @AuraEnabled
    public static String massApproveRecords( String selectedRows ) {
        
        System.debug( 'Selected Rows ' + selectedRows );
        String message = 'success';
        Set < Id > recordIdsToApprove = new Set < Id >();
        List < MassApprovalWrapper > listMAWs = ( List < MassApprovalWrapper > )JSON.deserialize( selectedRows, List < MassApprovalWrapper >.class );
        List < Approval.ProcessWorkitemRequest > approvalRequests = new List < Approval.ProcessWorkitemRequest >();
        
        for ( MassApprovalWrapper objMAW : listMAWs ) {
            
            //recordIdsToApprove.add( objMAW.PIWId );
            Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
            req.setComments( 'Approving the Request' );
            req.setAction( 'Approve' );
            req.setWorkitemId( objMAW.PIWId );
            approvalRequests.add( req );
            
        }               
        
        try {
            
            Approval.process( approvalRequests );
            
        } catch ( Exception e ) {
            
            message = 'error';
            System.debug( 'Error is ' + e.getMessage() );
            
        }
        
        return message;
        
    }
    
    public class MassApprovalWrapper {
        
        @AuraEnabled
        public String PIWId;
        @AuraEnabled
        public String status;
        @AuraEnabled
        public String objectRecordId;
        @AuraEnabled
        public String name;
        @AuraEnabled
        public String objType;
        
    }
    
}

HTML:

<template>
    <lightning-card>
        <lightning-datatable
            key-field="PIWId"
            data={records}
            columns={columns}
            onrowselection={handleSelect}
            onrowaction={handleRowAction}>
        </lightning-datatable>        
        <p slot="footer">
            <lightning-button label="Approve" variant="brand" onclick={approveRecords}></lightning-button>
        </p>
    </lightning-card>
</template>

JavaScript:

import { LightningElement, wire, api } from 'lwc';
import fetchPendingApprovalRecords from '@salesforce/apex/MassApprovalController.fetchPendingApprovalRecords';
import massApproveRecords from '@salesforce/apex/MassApprovalController.massApproveRecords';
import { NavigationMixin } from 'lightning/navigation';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

const ACTIONS = [
    { label: 'View', name: 'view' }
];
const COLUMNS = [
    { label: 'Name', fieldName: 'name' },
    { label: 'Type', fieldName: 'objType' },
    { label: 'Status', fieldName: 'status' },
    {
        type: 'action',
        typeAttributes: { rowActions: ACTIONS }
    }
];

export default class MassApproval extends NavigationMixin( LightningElement ) {

    records;
    wiredRecords;
    error;
    columns = COLUMNS;
    selectedRows;

    @wire( fetchPendingApprovalRecords )  
    wiredAccount( value ) {

        const { data, error } = value;
        this.wiredRecords = value;

        if ( data ) {
                            
            this.records = data;
            console.log( 'Records are', JSON.stringify( this.records ) );

        } else if ( error ) {

            console.log( JSON.stringify( error ) );
            this.records = undefined;

        }

    }  

    handleRowAction( event ) {

        const row = event.detail.row;
        console.log( 'Row is', JSON.stringify( row ) );
        this[ NavigationMixin.Navigate ]( {
            type: 'standard__recordPage',
            attributes: {
                recordId: row.objectRecordId,
                actionName: 'view'
            }
        } );

    }

    handleSelect( event ) {

        this.selectedRows = event.detail.selectedRows;

    }

    @api async approveRecords() {

        console.log( 'Selected Rows are', JSON.stringify( this.selectedRows ) );

        await massApproveRecords( { selectedRows: JSON.stringify( this.selectedRows ) } )    
        .then ( result => {  

            console.log( result );  
            
            if ( result == 'success' ) {

                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Approval',
                        message: 'Records are approved',
                        variant: 'success',
                    }),
                );

            } else {

                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Approval',
                        message: 'Some error occured. Please check with your system admin!',
                        variant: 'error',
                    }),
                );

            }

        })  
        .catch( error => {  

            console.log( JSON.stringify( error ) );  

        });

        refreshApex( this.wiredRecords );

    }

}

JS-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

Output:

Leave a Reply