1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
public without sharing class lexBatchApprovalRecordsController {
    //Wrapper class to store the column values of data table
    public class SubmittedRecordsWrapper{
        @AuraEnabled public Id workItemId;
        @AuraEnabled public String recordId;
        @AuraEnabled public String relatedTo;
        @AuraEnabled public String recordName;
        @AuraEnabled public String nameUrl;
        @AuraEnabled public String submittedBy;
        @AuraEnabled public String submittercomment;
        @AuraEnabled public Date submittedDate;
        @AuraEnabled public String comments;
        @AuraEnabled public String proD;
    }
    @AuraEnabled (cacheable=true)
    public static integer gettotalcount()
    {
        Integer icount = 0;
        //Add By Li Jun 20231026 Start
        // List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE (OriginalActorId = : UserInfo.getUserId() and ActorId = null) OR ActorId = : UserInfo.getUserId()]);
        // 20231202 ljh  start
        // List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE  ActorId = : UserInfo.getUserId() ]);
        // Set<Id> piSet = new Set<Id>();
        // for(ProcessInstanceWorkitem piwi:piwList){
        //     piSet.add(piwi.ProcessInstanceId);
        // }
        // if(piSet.isEmpty()){
        //     return 0;
        // }
        // for(ProcessInstance ps : [SELECT Id,TargetObjectId,TargetObject.Name,CreatedDate,ProcessDefinitionId,
        //                          (SELECT ID,CreatedBy.Name FROM WorkItems WHERE  ActorId = : UserInfo.getUserId()),
        //                          (SELECT Id,OriginalActor.Name,Comments,CreatedById,CreatedBy.Name FROM Steps WHERE StepStatus = 'Started') FROM ProcessInstance WHERE id in:piSet]){
        //     if(!ps.WorkItems.isEmpty()&&!ps.steps.isEmpty()){
        //         icount++;
        //     }
        // }
        List<ProcessInstanceWorkitem> piwList = [SELECT Id FROM  ProcessInstanceWorkitem where Actorid = : UserInfo.getUserId() and ProcessInstance.status = 'Pending'];
        icount = piwList.size();
        // 20231202 ljh  end
        return icount;
    }
    @AuraEnabled
    public static List<SubmittedRecordsWrapper> getSubmittedRecords(Integer queryLimit, Integer queryOffset){
        system.debug('queryLimit'+queryLimit);
        system.debug('queryOffset'+queryOffset);
        List<SubmittedRecordsWrapper> lstSubmissionWrapper = new List<SubmittedRecordsWrapper>();
        //Process instance stores the info of records submitted for approval,
        // Process instance work item are the records an approver sees while approving/rejecting, Process instance step stores approved/rejected record including approva;/rejection comments
        //Add By Li Jun 20231026 Start
        //李文涛 修改
        // List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE (OriginalActorId = : UserInfo.getUserId() and ActorId = null) OR ActorId = : UserInfo.getUserId()]);
        // 20231202 ljh start
        // List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE  ActorId = : UserInfo.getUserId()]);
        List<ProcessInstanceWorkitem> piwList = [SELECT Id,ProcessInstanceId FROM  ProcessInstanceWorkitem where Actorid = : UserInfo.getUserId() and ProcessInstance.status = 'Pending'];
        // 20231202 ljh end
        Set<Id> piSet = new Set<Id>();
        for(ProcessInstanceWorkitem piwi:piwList){
            piSet.add(piwi.ProcessInstanceId);
        }
        //Add By Li Jun 20231026 Start
        for(ProcessInstance ps : [SELECT Id,TargetObjectId,TargetObject.Name,CreatedDate,ProcessDefinitionId,
                                 (SELECT ID,CreatedBy.Name FROM WorkItems WHERE  ActorId = : UserInfo.getUserId()),
                                 (SELECT Id,OriginalActor.Name,Comments,CreatedById,CreatedBy.Name FROM Steps WHERE StepStatus = 'Started') FROM ProcessInstance WHERE id in:piSet
                                 ORDER BY CreatedDate DESC LIMIT :queryLimit OFFSET :queryOffset]){
            if(!ps.WorkItems.isEmpty()){
                SubmittedRecordsWrapper objSubmittedRecordsWrapper = getSubmitRecord(ps);
                if(!ps.steps.isEmpty()){
                    if(ps!=null && ps.WorkItems!=null && ps.WorkItems.size() > 0){
                        objSubmittedRecordsWrapper.submittedBy = ps.WorkItems[0].CreatedBy.Name;
                    }
                    if(ps.steps[0].Comments == '' || ps.steps[0].Comments == null)
                    objSubmittedRecordsWrapper.submittercomment = 'No comments from submitter';
                    else
                    objSubmittedRecordsWrapper.submittercomment = ps.steps[0].Comments;
                    lstSubmissionWrapper.add(objSubmittedRecordsWrapper);
                }
            }
        }
        system.debug(JSON.serialize(lstSubmissionWrapper));
        return lstSubmissionWrapper;
    }
    public static SubmittedRecordsWrapper getSubmitRecord(ProcessInstance ps){
        SubmittedRecordsWrapper objSubmittedRecordsWrapper = new SubmittedRecordsWrapper();
        if(ps!=null && ps.WorkItems!=null && ps.WorkItems.size() > 0){
            objSubmittedRecordsWrapper.workItemId = ps.WorkItems[0].Id;
        }
        objSubmittedRecordsWrapper.recordId = ps!=null && ps.TargetObjectId!=null?ps.TargetObjectId:null;
        objSubmittedRecordsWrapper.recordName = ps!=null && ps.TargetObject!=null ?ps.TargetObject.Name:'';
        if(ps!=null && ps.WorkItems!=null && ps.WorkItems.size() > 0){
            objSubmittedRecordsWrapper.nameUrl = '/lightning/r/'+ ps.WorkItems[0].Id+'/view';
        } 
        objSubmittedRecordsWrapper.comments = '';
        objSubmittedRecordsWrapper.relatedTo =getObjectName(ps.TargetObjectId);
        objSubmittedRecordsWrapper.submittedDate = ps!=null && ps.CreatedDate!=null? Date.newInstance(ps.CreatedDate.year(),ps.CreatedDate.month(),ps.CreatedDate.day()):Date.today();
        return objSubmittedRecordsWrapper;
    }
    public static String getObjectName(String recordId){
        //To get the label of the object name using Schema methods
        String keyPrefix = recordId.subString(0,3);
        String objectName = '';
        Map<String,Schema.SObjectType> sobjectTypeMap = Schema.getGlobalDescribe();
        for(String obj : sobjectTypeMap.keySet()){
            Schema.DescribeSObjectResult sobjectResult = sobjectTypeMap.get(obj).getDescribe();
            String getKeyPrefix = sobjectResult.getKeyPrefix();
            if(keyPrefix.equals(getKeyPrefix)){
                objectName = sobjectResult.getLabel();
                break;
            }
        }
        return objectName;
    }
    
    @AuraEnabled
    public static String processRecords(String processType,String strwraprecs,String comment){
        system.debug('processType'+processType);
        system.debug('wraprecs'+strwraprecs);
        List<SubmittedRecordsWrapper> wraprecs = (List<SubmittedRecordsWrapper>)System.JSON.deserialize(strwraprecs, List<SubmittedRecordsWrapper>.class);
        Map<string,SubmittedRecordsWrapper> mapSubmittedRecordsWrapper = new map<String,SubmittedRecordsWrapper>();
        List<String> lstWorkItemIds = new List<String>();
        for(SubmittedRecordsWrapper iwrap: wraprecs)
        {
            mapSubmittedRecordsWrapper.put(iwrap.workItemId,iwrap);
            lstWorkItemIds.add(iwrap.workItemId);
        }
        
        //Approve,reject the record programmatically
        String message = ''; 
        Integer recordsProcessed = 0;
        String comments = processType == 'Approve' ? 'Approved' : 'Rejected';
        List<Approval.ProcessWorkitemRequest> lstWorkItemRequest = new List<Approval.ProcessWorkitemRequest>();//ProcessWorkitemRequest class has methods to programmatically process submitted records
        for(String workItemId : lstWorkItemIds){
            Approval.ProcessWorkitemRequest objWorkItemRequest = new Approval.ProcessWorkitemRequest();
            if(mapSubmittedRecordsWrapper.containsKey(workItemId)&&!String.isBlank(mapSubmittedRecordsWrapper.get(workItemId).comments)){
                objWorkItemRequest.setComments(mapSubmittedRecordsWrapper.get(workItemId).comments);
            }else{
                objWorkItemRequest.setComments(comment);
            }
            objWorkItemRequest.setAction(processType);//approve or reject
            objWorkItemRequest.setWorkitemId(workItemId);
            lstWorkItemRequest.add(objWorkItemRequest);
        }
        Approval.ProcessResult[] lstProcessResult = Approval.process(lstWorkItemRequest,FALSE);//process method is used for approving/rejecting records depending on setAction attribute
        for(Approval.ProcessResult processResult : lstProcessResult){
            if(processResult.isSuccess()){
                recordsProcessed++;
            }
            else{
                for(Database.Error error : processResult.getErrors()){
                    message += error.getMessage();
                }
            }
        }
        if(recordsProcessed == lstWorkItemIds.size()){
            message = 'All records are '+comments+' successfully';
        }
        return message;
        // return 'success';
    }
}