Salesforce 動態審批


由於Salesforce只支持根據條件動態選擇審批分支,如果我們想進一步支持動態根據頁面的某種條件選擇審批人,Salesforce是不支持的。因此我們只能通過override salesforce審批類來實現,具體步驟如下:

0,以管理員身份新建立一個審批流為Opportunity(審批流名稱和每個節點的名稱我們從寫時候時候需要用到)

1,添加一個名稱為Submit for Approval By Neo 自定義按鈕給Opportunity(由於我們要重寫的是Opportunity的審批流)在Opportunity Object 中的 ‘Buttons, Links, and Actions’ 如下:

填完后填寫js代碼,由於我們想通過點擊直接啟動工作流,所以我們需要在這里通過js 調用webservice 類啟動。代碼如下:

1 <!--參數名區分大小寫,對於跨層object直接在Object名后直接加參字段名即可-->
2 {!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}
3 {!REQUIRESCRIPT("/soap/ajax/30.0/apex.js")}
4 
5 var OppID='{!Opportunity.Id}'
6 var Comments = 'submited'
7 var OppSubmitter = '{!$User.Id}'
8 var result = sforce.apex.execute("OppApprovalProcess", "SubmitforApproval", {oppID:OppID,Comments:Comments,userID:OppSubmitter });
9 window.location.reload()

2,在這里我們看到我們需要調用OppApprovalProcess類下SubmitforApproval方法實現審批的提交,下面就是調用提交的代碼:(里面還還涉及動態選擇審批人的問題,我們后邊會講到)

 1 global class OppApprovalProcess {
 2     
 3     //submit 
 4     webservice static boolean SubmitforApproval(string oppID, string Comments, string userID)
 5     {
 6         try
 7         {
 8             system.debug('oppID:'+oppID);
 9             User nextapprover = getApprover(oppID);;
10             Approval.ProcessSubmitRequest subReq = new Approval.ProcessSubmitRequest();
11             subReq.setComments(Comments);
12             subReq.setObjectId(oppID);
13             subReq.setSubmitterId(userID);
14             subReq.setNextApproverIds(new Id[]{nextapprover.Id});
15             subReq.setProcessDefinitionNameOrId('Opportunity_Discount');
16             Approval.ProcessResult submitResult = Approval.process(subReq);
17                 
18             return submitResult.isSuccess();
19         }
20         catch(Exception ex)
21         {
22             system.debug('ex:'+ex.getMessage());
23             return false;
24         }
25     }
26

3,創建完按鈕后,我們需要把這個自定義按鈕添加到page layout中,我們的最終目的是在添加完成后替換原有默認的提交按鈕,所以我們要重寫原有的Opportunity的Detail頁面通過Jquery進行代碼注入,所以我們要新建一個vistualforce 頁面代碼如下:

 1 <apex:page sidebar="true" standardController="Opportunity">
 2    <!-- <apex:relatedList list="ProcessSteps" ></apex:relatedList>-->
 3     <apex:includescript value="{!$Resource.JQuery}"/>
 4     <script type="text/javascript">
 5        $(function(){
 6             
 7            //添加新按鈕隱藏老按鈕
 8            // alert($('input[name="piSubmit"]').val());
 9            if($('input[name="piSubmit"]').val()=='Submit for Approval')
10            {            
11                    ($('input[name="piSubmit"]').hide()).parent().append($('input[name="submit_for_approval"]'));
12                     $('input[name="piSubmit"]').next().hide();
13             }
14             else
15             {
16                   //alert($('input[name="piSubmit"]').val());
17                     $('input[name="submit_for_approval"]').hide();
18                     //替換HistoryList中的審批鏈接
19                    var OppId = ('{!Opportunity.Id}').substring(0,15);
20                    var ApprovalListID = OppId + '_RelatedProcessHistoryList_body';
21                    //alert(ApprovalListID);
22                    var Approvalprocessdiv=document.getElementById(ApprovalListID);
23                    //alert(Approvalprocessdiv.getAttribute('class'));
24                    if(Approvalprocessdiv!=null)
25                    {
26                        var originalHTML=Approvalprocessdiv.innerHTML;
27                        var newHtml=originalHTML.replace('/p/process/ProcessInstanceWorkitemWizardStageManager?','/apex/ProcessInstance?OppId='+OppId+'&');
28                        Approvalprocessdiv.innerHTML=newHtml;
29                    }
30             }
31        });
32     </script>
33     <apex:detail relatedList="true" title="true"/>
34 </apex:page>

添加完成后效果如下:submit for approval by Neo 就是我們的自定義按鈕 

 4,添加提交按鈕后,我們同時要替換審批頁面的同意和拒絕按鈕,但是由於salesforce不支持重寫這個頁面,所以我們自己創建一個審批頁面來替換salesforce默認的審批頁面,前端代碼如下:

 1 <apex:page controller="ProcessInstanceController" tabStyle="Opportunity">
 2    <apex:form >
 3    <apex:sectionHeader title="Opportunity" subtitle="{!objOpp.Name}"/>
 4    <apex:pageBlock title="Approve/Reject Approval Request">
 5        <apex:pageBlockButtons location="bottom"> 
 6            <apex:commandButton value="Approve" action="{!Approval}" reRender="block">
 7                    <apex:param name="approve" value="Approve" assignTo="{!ApprovalAction}"/>
 8            </apex:commandButton>
 9            <apex:commandButton value="Reject" action="{!Approval}" reRender="block">
10                    <apex:param name="reject" value="Reject" assignTo="{!ApprovalAction}"/>
11            </apex:commandButton>
12            <apex:commandButton value="Cancel" action="{!Approval}" reRender="block">
13                    <apex:param name="cancel" value="Cancel" assignTo="{!ApprovalAction}"/>
14            </apex:commandButton>
15        </apex:pageBlockButtons>   
16        <apex:pageBlockSection columns="1">
17            <apex:pageBlockSectionItem >
18                Name <apex:outputField value="{!objOpp.Name}"/>
19            </apex:pageBlockSectionItem>
20            <apex:pageBlockSectionItem >
21                Lead Owner <apex:outputField value="{!objOpp.Owner.Name}"/>
22            </apex:pageBlockSectionItem>
23            <apex:pageBlockSectionItem >
24                Rejection Reason <font color="red">(Mandatory while Rejection)</font><apex:inputField value="{!objOpp.Rejection_Reason__c}"/>
25            </apex:pageBlockSectionItem>
26            <apex:pageBlockSectionItem >
27               Comments <font color="red">(Mandatory while Rejection)</font> <apex:inputTextArea value="{!objOpp.Comments__c}" rows="5" cols="100"/>
28            </apex:pageBlockSectionItem>
29        </apex:pageBlockSection>
30    </apex:pageBlock>
31    </apex:form>
32 </apex:page>

5,同時在后台類中重寫Apprve 和 Reject 類,代碼如下:

 1 public class ProcessInstanceController {
 2     public String processId;
 3     public String OppId;
 4     public ProcessInstance objProcessInstance;
 5     public Opportunity objOpp {get; set;}
 6     public string ApprovalAction {get;set;}
 7     public PageReference redirectPage;
 8     //初始化
 9     public ProcessInstanceController()
10     {
11         processId = ApexPages.currentPage().getParameters().get('id'); //獲取當前的工作流ID
12         OppId = ApexPages.currentPage().getParameters().get('OppId'); //獲取當前case ID
13         objOpp = [select Name,Owner.Name,Rejection_Reason__c,Comments__c from Opportunity where id =:OppId]; //獲取當前Opp對象為了后面更新comments和Reson
14         redirectPage = new PageReference('/'+OppId);
15      }
16     //審批
17      public PageReference Approval(){   
18       try
19         {
20             if(ApprovalAction == 'Approve' || ApprovalAction == 'Reject')
21             {
22                 //system.debug('ApprovalAction:'+this.ApprovalAction);
23                 User nextapprover =[select Id from User where username = 'yinghai_guo_neo@sina.com'];//新建立一個object 並mapping關系
24                 Approval.ProcessWorkitemRequest approvalNode = new Approval.ProcessWorkitemRequest();
25                // system.debug('comments:'+objOpp.Comments__c);
26                 approvalNode.setComments(objOpp.Comments__c);
27                 approvalNode.setAction(ApprovalAction);
28                 approvalNode.setNextApproverIds(new Id[]{nextapprover.Id});                
29                 approvalNode.setWorkitemId(processId);
30                 //system.debug('processID'+processId);
31                 Approval.ProcessResult result = Approval.process(approvalNode);
32                 //system.debug('result:'+result.isSuccess());
33                 update objOpp;
34                 //system.debug('update objOpp');
35              }
36             else
37             {
38                 //system.debug('ApprovalAction:'+this.ApprovalAction);
39             }
40         }
41         catch(Exception ex)
42         {
43             system.debug('Ex:'+ex.getMessage());
44          }
45          return redirectPage;
46     }
47 }

最后生成的審批頁面效果如下:

 

6, 最后我們要做的事情就是在動態查找審批人的方法,我們通過判斷審批的每個節點等條件賽選出最終審批人

 1  //get approver
 2     private static User getApprover(string OppID)
 3     {
 4          string ProcessNodeName = 'Sumbit';
 5         //獲取當前需要審批節點名稱
 6         for (ProcessInstance piw:[select Id,(SELECT ProcessNode.Name FROM StepsAndWorkitems) 
 7                           FROM ProcessInstance where TargetObjectId = :OppID order by CreatedDate])
 8         {
 9             for(ProcessInstanceHistory PIH : piw.StepsAndWorkitems)
10               {
11                 ProcessNodeName=PIH.ProcessNode.Name;
12                 break;
13               }
14         }
15         User nextApprover = null;
16         if(ProcessNodeName == 'Submit')
17         {
18             //do sth
19         }
20         else if(ProcessNodeName == 'Director Approval')
21         {
22             //do sth
23         }
24         else if(ProcessNodeName == 'CEO Approval')
25         {
26             //do sth
27         }
28         
29         return nextApprover;
30     }

7,由於我們的opportunity 的頁面是我們自定義的,所以我們要在系統中替換Opportunity list View按鈕中的鏈接子頁面,我們直接在Buttons, Links, and Actions修改,截圖如下:

至此,我們實現審批人的動態審批,有任何問題,留言討論,謝謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM