Skip to content

Instantly share code, notes, and snippets.

@amitastreait
Last active October 12, 2023 10:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amitastreait/eaadf6aa4be8fbabd7748eabc6a57d4d to your computer and use it in GitHub Desktop.
Save amitastreait/eaadf6aa4be8fbabd7748eabc6a57d4d to your computer and use it in GitHub Desktop.
Approve Reject records from the Apex Class using Lightning Flow or Apex Class
<template>
<lightning-card variant="Narrow">
<lightning-spinner alternative-text="Loading" size="small" variant="brand" if:true={isloading} ></lightning-spinner>
<div class="slds-p-around_small">
<lightning-button-group>
<lightning-button label="Approve" title="Approve" onclick={handleApprove}></lightning-button>
<lightning-button label="Reject" title="Reject" onclick={handleReject}></lightning-button>
<lightning-button if:true={showRecall} label="Recall" title="Recall" onclick={handleRevoke}></lightning-button>
</lightning-button-group>
</div>
<div class="slds-p-around_small">
<p class="slds-p-around_small" style="color: red;" if:true={errorDetails}>
{errorDetails}
</p>
<lightning-textarea message-when-value-missing="Approval/Rejections comments are required!"
name="comments" required label="Comments"
placeholder="provide the comments here ......" onchange={handleChange}>
</lightning-textarea>
</div>
</lightning-card>
</template>
import { LightningElement, api, wire } from 'lwc';
import id from '@salesforce/user/Id';
import approveRejectRecords from '@salesforce/apex/ApprovalUtil.approveRejectRecords';
import getTargetObjectId from '@salesforce/apex/ApprovalUtil.getTargetObjectId';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class Approval extends LightningElement {
@api recordId;
@api message = '🤦‍♂️ You can not Approve/Reject the record as you have submitted the record for Approval';
@api canapprove = false;
userId = id;
commments;
isloading = false;
targetObjectId;
errorDetails;
submitterId;
showRecall = false;
get approve() {
return this.canapprove;
}
set approve(value) {
this.canapprove = value;
}
@wire(getTargetObjectId, { recordId: '$recordId' })
wiredData({ error, data }) {
if (data) {
console.log('Data \n ', data);
if (data.ProcessInstance && data.ProcessInstance.TargetObjectId) {
this.targetObjectId = data.ProcessInstance.TargetObjectId;
}
this.submitterId = data.CreatedById;
if (this.userId === this.submitterId) {
this.showRecall = true;
} else {
this.showRecall = false;
}
console.log('TargetObjectId ', this.targetObjectId);
} else if (error) {
console.error('Error: \n ', error);
}
}
handleReject(event) {
event.preventDefault();
this.handleApproveRejectRecords('Reject', 'rejected');
}
handleApprove(event) {
event.preventDefault();
this.handleApproveRejectRecords('Approve', 'approved');
}
handleRevoke(event) {
event.preventDefault();
this.handleApproveRejectRecords('Removed', 'recalled');
}
handleApproveRejectRecords(actionName, title) {
let allValid = this.validateInput();
if (!this.canapprove && this.submitterId === this.userId) {
this.errorDetails = this.message;
return;
}
if (!allValid) {
return;
}
this.errorDetails = '';
this.isloading = true;
let recordIds = [];
recordIds.push(this.targetObjectId);
let inputParameters = {
recordIds: recordIds,
actionName: actionName,
comments: this.commments,
assignNextApprovers: false,
submitterId: this.submitterId
}
approveRejectRecords({
inputWrapper: JSON.stringify(inputParameters)
})
.then((response) => {
console.log('successfull ', response);
this.dispatchEvent(new ShowToastEvent({
title: 'Success',
message: 'The record has been ' + title,
variant: 'success'
}));
})
.catch((error) => {
console.error('Error while performing the approval action! \n ', JSON.stringify(error))
this.errorDetails = 'Unknown error';
if (Array.isArray(error.body)) {
this.errorDetails = error.body.map(e => e.message).join(', ');
} else if (typeof error.body.message === 'string') {
this.errorDetails = error.body.message;
}
this.dispatchEvent(new ShowToastEvent({
title: 'Error',
message: 'There was an error while processing the approval action',
variant: 'error'
}));
})
.finally(() => {
this.isloading = false;
})
// Call the Apex Class to do approve or reject records
}
handleChange(event) {
event.preventDefault();
this.commments = event.target.value;
}
validateInput() {
const allValid = [
...this.template.querySelectorAll('lightning-textarea'),
].reduce((validSoFar, inputCmp) => {
inputCmp.reportValidity();
return validSoFar && inputCmp.checkValidity();
}, true);
return allValid;
}
}
global class ApprovalUtil {
@AuraEnabled(cacheable=true)
global static sObject getTargetObjectId(String recordId){
return [SELECT Id, ProcessInstanceId,
ProcessInstance.TargetObjectId,
OriginalActorId,
ActorId,
CreatedById
FROM
ProcessInstanceWorkitem
WHERE
Id =: recordId
LIMIT
1
];
}
@AuraEnabled
global static void approveRejectRecords(String inputWrapper){
ApprovalWrapper inputWrapperObject = (ApprovalWrapper)JSON.deserialize(inputWrapper, ApprovalWrapper.class);
approveRejectRecords(inputWrapperObject);
}
global static void approveRejectRecords(ApprovalWrapper inputWrapper){
List<Id> recordIds = inputWrapper.recordIds;
System.debug('inputWrapper \n '+ JSON.serializePretty(inputWrapper));
Map<Id, ProcessInstance> processIntanceMap = new Map<Id, ProcessInstance>([
SELECT Id, ProcessDefinitionId, TargetObjectId
FROM
ProcessInstance
WHERE
TargetObjectId IN : recordIds AND
Status = 'Pending'
]);
Map<Id, ProcessInstanceWorkitem> processInstanceWorkitemsMap = new Map<Id, ProcessInstanceWorkitem>([
SELECT Id, ProcessInstanceId
FROM
ProcessInstanceWorkitem
WHERE
ProcessInstanceId IN : processIntanceMap.keySet()
]);
List<Approval.ProcessWorkitemRequest> allWorkItemRequest = new List<Approval.ProcessWorkitemRequest>();
for (ProcessInstanceWorkitem item : processInstanceWorkitemsMap.values()){
Approval.ProcessWorkitemRequest req2 = new Approval.ProcessWorkitemRequest();
req2.setComments( inputWrapper.comments);
req2.setAction(inputWrapper.actionName ); // To Approve Provide Approve & to recall provide Removed
if(inputWrapper.assignNextApprovers){
req2.setNextApproverIds( inputWrapper.nextApprovars );
}
req2.setWorkitemId(item.Id);
// Add the request for approval
allWorkItemRequest.add(req2);
}
Approval.ProcessResult[] result2 = Approval.process(allWorkItemRequest);
}
@InvocableMethod(label = 'Approve/Reject Records' category ='Approval' description='Approval Process Methods')
global static void approveRejectRecords(List<ApprovalWrapper> inputWrapper){
if( inputWrapper != null && inputWrapper.size() > 0){
approveRejectRecords( inputWrapper.get(0) );
}
}
global class ApprovalWrapper{
@AuraEnabled @InvocableVariable(label='Id of the Record' description='Id of the Record')
global List<Id> recordIds;
@AuraEnabled @InvocableVariable(label='Action to perform! either Reject or Approve' description='Action to perform! either Reject or Approve')
global String actionName;
@AuraEnabled @InvocableVariable(label='Rejection or Approval Comments' description='Rejection or Approval Comments')
global String comments;
@AuraEnabled @InvocableVariable(label='Next Approval User Id' description='Next Approval User Id')
global List<Id> nextApprovars;
@AuraEnabled @InvocableVariable(label='Assign to next Approver' description='Assign to next Approver')
global Boolean assignNextApprovers;
@AuraEnabled @InvocableVariable(label='Id of the user who submitted the approval' description='Id of the user who submitted the approval')
global String submitterId;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment