在閱讀此篇文章前,可以先參考閱讀一個前輩總結的關於Approval Process的操作。以下為參考的鏈接:
http://www.cnblogs.com/mingmingruyuedlut/p/3765777.html
Approval Process用於流程審批,Apex主要涉及到的命名空間和類為Approval命名空間以及System命名空間下的Approval類。
其中Approval命名空間下主要的類為:
- ProcessRequest
- ProcessSubmitRequest
- ProcessWorkitemRequest
- ProcessResult
下面通過一段代碼來進行介紹這些類的作用以及使用方式,此代碼copy於官方PDF文檔的sample。
1 public class TestApproval { 2 void submitAndProcessApprovalRequest() { 3 // Insert an account 4 Account a = new Account(Name='Test',annualRevenue=100.0); 5 insert a; 6 User user1 = [SELECT Id FROM User WHERE Alias='SomeStandardUser']; 7 // Create an approval request for the account 8 Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest(); 9 req1.setComments('Submitting request for approval.'); 10 req1.setObjectId(a.id); 11 // Submit on behalf of a specific submitter 12 req1.setSubmitterId(user1.Id); 13 // Submit the record to specific process and skip the criteria evaluation 14 req1.setProcessDefinitionNameOrId('PTO_Request_Process'); 15 req1.setSkipEntryCriteria(true); // Submit the approval request for the account 16 Approval.ProcessResult result = Approval.process(req1); // Verify the result 17 System.assert(result.isSuccess()); 18 System.assertEquals( 'Pending', result.getInstanceStatus(), 'Instance Status'+result.getInstanceStatus()); 19 // Approve the submitted request 20 // First, get the ID of the newly created item 21 List<Id> newWorkItemIds = result.getNewWorkitemIds(); 22 // Instantiate the new ProcessWorkitemRequest object and populate it 23 Approval.ProcessWorkitemRequest req2 = new Approval.ProcessWorkitemRequest(); 24 req2.setComments('Approving request.'); 25 req2.setAction('Approve'); 26 req2.setNextApproverIds(new Id[] {UserInfo.getUserId()}); 27 // Use the ID from the newly created item to specify the item to be worked 28 req2.setWorkitemId(newWorkItemIds.get(0)); 29 // Submit the request for approval 30 Approval.ProcessResult result2 = Approval.process(req2); 31 // Verify the results 32 System.assert(result2.isSuccess(), 'Result Status:'+result2.isSuccess()); 33 System.assertEquals( 'Approved', result2.getInstanceStatus(), 'Instance Status'+result2.getInstanceStatus()); 34 } 35 }
注:此代碼無法直接運行,如果需要運行此代碼,請參照上方的鏈接為Account表設置名為'PTO_Request_Process'的審批流程。
通過上述代碼來更好的了解以下的類的使用。
一)ProcessRequest
ProcessRequest類作為ProcessSubmitRequest和ProcessWorkitemRequest類的父類,提供了四個內置方法:
- setComments(comments):此方法用於設置審批提交時的審批意見;
- setNextApproverIds(ID[] nextApproverIds):此方法用於流程審批的下一級審批者;
- getComments():此方法用於獲取審批意見;
- getNextApproverIds():返回一個作為審批者的用戶的用戶ID列表。
ProcessRequest封裝的方法為最基礎的流程審批方法,並且這些方法都是實例化方法。通常新建流程審批的類時並不實例化此類,而是實例化他對應的兩個子類。
二)ProcessSubmitRequest
使用此類來提交一條記錄到流程審批中,除繼承ProcessRequest類方法以外,如下為自身的方法:
- setObjectId(recordId):設置指定的sObject的記錄ID到流程審批中。如上述sample中,insert一條Account,可以將Account提交到審批流程中,比如annualRevenue字段超過多少情況下執行流程審批
- setProcessDefinitionNameOrId(nameOrId):設置流程定義的名稱或者編號,記錄提交給特定的審批流程。可以在salesforce中通過setup->Create->Workflow&Approvals->Approval Processes設置指定的審批流程,如果設置為null,則遵循標准流程,默認值為null;
- setSkipEntryCriteria(skipEntryCriteria):如果skipEntryCriterial設置為true,請求提交則跳過在setProcessDefinitionNameOrId流程設置中的校驗,如果沒有指定nameOrId則自動忽略此參數,並且按照標准流程順序走。如果設置為false,或不調用此方法,則不跳過校驗;
- setSubmittedId(userId):設置需要提交到流程審批的記錄的用戶ID,這個用戶必須是在流程定義設置中允許提交流程的一個用戶,如果不設置則默認當前用戶;
- 相應get方法。
通過此類的方法講解可以看出此類主要用於將一條數據提交到流程審批時使用。
三)ProcessWorkitemRequest
此類用於當一個記錄提交到流程審批后,處理一個流程審批的請求,處理的狀態可以分為Approve,Reject,Removed三種情況。除繼承ProcessRequest類的方法以外,如下為自身的方法:
- setAction(actionType):設置action類型來處理一個流程審批請求,其中actionType可以為一下的值:Approve,Reject,Removed.其中,只有系統管理員可以指定Removed;
- setWorkitemId(id):設置被批准,拒絕或者移除的審批請求的編號,此編號可以在ProcessInstanceWorkitem表中獲取,此表為salesforce自身封裝的表;
- 相應的get方法。
通過此類的方法介紹可以看出,此類主要用於對已經提交到流程審批的記錄進行審批處理時用到的類。
四)ProcessResult
當提交一條記錄到流程審批后,可以通過此類來處理流程審批的結果狀態。
此類方法如下:
- getEntityId():獲取正在被提交到流程審批的記錄的編號,可以在ProcessInstanceWorkitem表中看到,對應於此表的字段TargetObjectId值;
- getErrors():如果發生錯誤,返回包含數據庫對象錯誤代碼和描述的數組;
- getInstanceId():獲取流程審批的編號,可以在ProcessInstanceWorkitem表中看到,對應於此表的字段Id值;
- getInstanceStatus():獲取流程審批的狀態,主要有以下的幾種:Approved,Reject,Removed,Pending;
- getNewWorkitemIds():獲取提交到流程審批的新項目的ID,可以有0個或者1個流程審批。可以在ProcessInstanceWorkitem表中看到,對應於此表的Id字段值;
- isSuccess():如果審批流程正常提交則返回true,否則返回false。
五)Approval
Approval位於System命名空間下,上述1-4均在Approval命名空間下。
Approval類含有很多方法,這里主要介紹process()方法,其他方法請自行查看官方PDF文檔。此方法作用為提交一個新的請求,或者通過或者拒絕已經存在的審批的記錄。此方法形參有一項為ProcessRequest,可以指定ProcessSubmitRequest或者ProcessWorkitemRequest類作為參數以實現不同功能,此方法返回類型為Approval.ProcessResult對象。當正確提交一條記錄到審批流程后,相應的ProcessInstanceWorkitem表以及ProcessInstance表便新增一條關於此條記錄的信息記錄。
總結:ProcessRequest作為審批請求的父類,封裝了兩個重要的方法,擴展的兩個子類分別實現不同功能,ProcessSubmitRequest實現將一條記錄傳到審批流程中,ProcessWorkitemRequest實現審批已經存在審批流程中的記錄。
對上述例子進行調整一下,使之可以不通過前輩那種方式(鏈接在上方)操作。
通過上面介紹可以發現,當將setProcessDefinitionNameOrId()方法參數設置為null或者不調用此方法時,可以不執行上述方法,通過定義父類的setNextApproverIds()方法設置審批用戶編號便可以將審批流程跑通,於是上述代碼可以做如下變形便直接跑通:
1 public class TestApproval { 2 public void submitAndProcessApprovalRequest() { 3 // Insert an account 4 Account a = new Account(Name='Test',annualRevenue=100.0); 5 insert a; 6 User user1 = [SELECT Id FROM User WHERE Alias='zero']; 7 // Create an approval request for the account 8 Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest(); 9 req1.setComments('Submitting request for approval.'); 10 req1.setObjectId(a.id); 11 // Submit on behalf of a specific submitter 12 req1.setSubmitterId(user1.Id); 13 ID[] ids = new ID[]{user1.Id}; 14 req1.setNextApproverIds(ids); 15 // Submit the record to specific process and skip the criteria evaluation 16 //req1.setProcessDefinitionNameOrId('PTO_Request_Process'); 17 req1.setSkipEntryCriteria(true); // Submit the approval request for the account 18 Approval.ProcessResult result = Approval.process(req1); // Verify the result 19 System.assert(result.isSuccess()); 20 System.assertEquals( 'Pending', result.getInstanceStatus(), 'Instance Status'+result.getInstanceStatus()); 21 // Approve the submitted request 22 // First, get the ID of the newly created item 23 List<Id> newWorkItemIds = result.getNewWorkitemIds(); 24 // Instantiate the new ProcessWorkitemRequest object and populate it 25 Approval.ProcessWorkitemRequest req2 = new Approval.ProcessWorkitemRequest(); 26 req2.setComments('Approving request.'); 27 req2.setAction('Approve'); 28 req2.setNextApproverIds(new Id[] {UserInfo.getUserId()}); 29 // Use the ID from the newly created item to specify the item to be worked 30 req2.setWorkitemId(newWorkItemIds.get(0)); 31 // Submit the request for approval 32 Approval.ProcessResult result2 = Approval.process(req2); 33 // Verify the results 34 System.assert(result2.isSuccess(), 'Result Status:'+result2.isSuccess()); 35 System.assertEquals( 'Approved', result2.getInstanceStatus(), 'Instance Status'+result2.getInstanceStatus()); 36 } 37 }
至於在setup->Create->Workflow&Approvals->Approval Processes新建一個自定義的審批流程使用比較好,還是在程序中動態設置下一個審批人比較好,看具體的項目要求吧。至於兩者有什么區別,本人並沒有太深入了解,有想更好了解的可以查看相關的論壇或者官方文檔查看。如果內容有錯誤的地方,請批評指正,如果有哪里不懂得可以留言和我聯系。