Salesforce 中的审批流程是一种自定义的自动化流程,用于管理记录的批准和审批流程。它允许组织定义一系列规则和步骤,确保关键业务操作(如销售报价、合同审批等)经过必要的审核和批准。
这个过程通常包括以下几个步骤:
- 定义批准规则:管理者可以定义在何种情况下记录需要批准以及需要谁来进行批准。这些规则可以基于条件、角色、层级等进行设置。
- 创建批准流程:一旦定义了批准规则,就需要创建具体的批准流程。这包括定义审批流程中的步骤、角色和条件,以确保审批流程符合业务需求。
- 提交记录:用户在系统中创建或更新记录时,如果满足了批准规则的条件,记录将会进入批准流程并被提交等待批准。
- 批准审批:批准流程中的审批者根据其角色和权限来审批记录。审批者可以通过电子邮件、Salesforce 应用或者 Salesforce1 移动应用来审批记录。
- 通知和跟进:在记录被批准或拒绝之后,相应的通知将会发送给相关人员。记录的审批历史和状态也会被记录下来,以供跟进和审计使用。
通过使用 Salesforce 中的审批流程,组织可以确保关键业务操作得到必要的审批和监督,提高业务流程的透明度和效率。

审批流程的创建和使用大家都很熟悉了,今天记录一下审批流程底层的一些内容,进行审批流程对象分析。
审批流程包含的对象:
- 处理定义(ProcessDefinition)
- 过程实例(ProcessInstance)
- 过程实例步骤(ProcessInstanceStep)
- 过程实例节点(ProcessInstanceNode)
- 批准请求(ProcessInstanceWorkitem)
- 批准历史(ProcessInstanceHistory)

-
处理定义(ProcessDefinition)
顾名思义,保存了环境中的审批流程,代表单一审批流程的定义,使用此对象读取审批流程的描述。该定义是只读的,无法修改 ProcessDefinition 对象中创建的记录,但可以查询和检索审批流程信息。
-- 例如
SELECT CreatedById,CreatedDate,Description,DeveloperName,LastModifiedById,LastModifiedDate,LockType,Name,State,SystemModstamp,TableEnumOrId,Type,Id
FROM ProcessDefinition
-
流程实例(ProcessInstance)
是只读对象。保存了环境中实际的审批流程的实例。即每条数据的整个审批流程作为一条数据,存在于这个对象中。
当过程中出现拒绝、取消等操作的时候,会增加记录。例如一条数据批准中途被撤回,这时候这条数据会产生一条过程实例数据,再次提交批准且批准后,还会产生一条数据。
![]()
-- 例如
SELECT CompletedDate,CreatedById,CreatedDate,ElapsedTimeInDays,ElapsedTimeInHours,ElapsedTimeInMinutes,Id,IsDeleted,LastActorId,LastModifiedById,LastModifiedDate,ProcessDefinitionId,Status,SubmittedById,SystemModstamp,TargetObjectId
FROM ProcessInstance
-
流程实例步骤(ProcessInstanceStep)
每个实例执行完成了哪些批准步骤(从进入审批流程开始),即过程实例(ProcessInstance)中的一条记录可能对应过程实例步骤(ProcessInstanceStep)中的多条记录。
它记录着所有经历过的步骤以及每个步骤的意见,所以其拥有Status字段用来记录审批的各个状态和Comments记录审批意见。
※存在Bug:当删除过程实例(ProcessInstance)的实例记录后,这个对象里的关联数据没有一起删除
另外,ProcessInstanceStep 和 ProcessInstanceWorkItem 两个对象都是为特定 ProcessInstance 创建的流程步骤的实例。 ProcessInstanceStep 表示审批流程 (ProcessInstance) 中用户已执行操作的步骤实例,ProcessInstanceWorkItem 表示审批流程 (ProcessInstance) 中待处理且用户下一步必须执行某些操作的步骤实例。我们查询和检索审批流程步骤和工作项。
-- 例如
SELECT ActorId,Comments,CreatedById,CreatedDate,ElapsedTimeInDays,Id,ElapsedTimeInHours,ElapsedTimeInMinutes,OriginalActorId,ProcessInstanceId,StepNodeId,StepStatus,SystemModstamp
FROM ProcessInstanceStep
-
流程实例节点(ProcessInstanceNode)
每个批准步骤的状态(只包含批准步骤)。有点类似过程实例步骤,但是比过程实例步骤少一个启动审批流程条件的步骤
-
审批请求(ProcessInstanceWorkitem)
保存等待批准(Pending)的申请
SELECT CreatedById,CreatedDate,ElapsedTimeInDays,ElapsedTimeInHours,ElapsedTimeInMinutes,Id,IsDeleted,OriginalActorId,ProcessInstanceId,ActorId,SystemModstamp
FROM ProcessInstanceWorkitem
-
审批历史(ProcessInstanceHistory)
是通过视图来表示的(开发者文档)
有时候我们需要获取审批的历史信息,用来进行相关审批节点的展示。这个时候我们就可以使用ProcessInstanceHistory。
ProcessInstanceHistory是salesforce提供的一个只读的,将ProcessInstanceWorkItem和ProcessInstanceStep结果结合在一起的审批历史表,通常情况下搜索时建议使用子查询方式查询。
通过ProcessInstance进行子查询:
SELECT Id, (SELECT Id, StepStatus, Comments FROM StepsAndWorkitems) FROM ProcessInstance

| _ | Id | StepsAndWorkitems | StepsAndWorkitems.totalSize | StepsAndWorkitems.done | StepsAndWorkitems.records | StepsAndWorkitems.records.0 | StepsAndWorkitems.records.0.Id | StepsAndWorkitems.records.0.StepStatus | StepsAndWorkitems.records.0.Comments | StepsAndWorkitems.records.1 | StepsAndWorkitems.records.1.Id | StepsAndWorkitems.records.1.StepStatus | StepsAndWorkitems.records.1.Comments | StepsAndWorkitems.records.2 | StepsAndWorkitems.records.2.Id | StepsAndWorkitems.records.2.StepStatus | StepsAndWorkitems.records.2.Comments |
| [ProcessInstance] | 04g7F0000092s4MQAQ | [object Object] | 1 | TRUE | [object Object] | [ProcessInstanceHistory] | 04i7F000009n61EQAQ | Pending | |||||||||
| [ProcessInstance] | 04g7F00000FfySuQAJ | [object Object] | 3 | TRUE | [object Object],[object Object],[object Object] | [ProcessInstanceHistory] | 04i7F00000GAQwDQAX | Pending | [ProcessInstanceHistory] | 04h7F00000SOEMpQAP | Started | 初次提交审批 | [ProcessInstanceHistory] | 04h7F00000SOENEQA5 | Approved | User01手动批准 |
补充:代码实现审批流程
Approval命名空间下主要的类为:
ProcessRequest
ProcessSubmitRequest
ProcessWorkitemRequest
ProcessResult
审批流程专用对象对应的审批流程:

// 审批流程专用对象触发器
trigger AprovalProcessObjTrigger on AprovalProcessObj__c(After insert, After update)
{
for (Integer i = 0; i < Trigger.new.size(); i++)
{
try
{
if( Trigger.isInsert || (Trigger.new[i].Next_Step__c == 'Submit' && Trigger.old[i].Next_Step__c != 'Submit'))
{
submitForApproval(Trigger.new[i]);
}
else if(Trigger.isInsert || (Trigger.new[i].Next_Step__c == 'Approve' && Trigger.old[i].Next_Step__c != 'Approve'))
{
approveRecord(Trigger.new[i]);
}
else if(Trigger.isInsert || (Trigger.new[i].Next_Step__c == 'Reject' && Trigger.old[i].Next_Step__c != 'Reject'))
{
rejectRecord(Trigger.new[i]);
}
}catch(Exception e)
{
// Trigger.new[i].addError(e.getMessage());
}
}
/**
* This method will submit the AprovalProcessObj__c automatically
**/
public void submitForApproval(AprovalProcessObj__c apo)
{
// Create an approval request for the AprovalProcessObj__c
Approval.ProcessSubmitRequest req1 = new Approval.ProcessSubmitRequest();
System.debug('审批流程专用对象记录Id: ' + apo.id);
System.debug('下一个批准人: ' + apo.Next_Approver__c);
req1.setComments('使用Trigger自动提交批准请求。');
req1.setObjectId(apo.id);
req1.setNextApproverIds(new Id[] {apo.Next_Approver__c});
// Submit the approval request for the AprovalProcessObj__c
Approval.ProcessResult result = Approval.process(req1);
System.debug('批准结果: ' + result);
System.debug('批准结果STR: ' + string.valueOf(result));
}
/**
* Get ProcessInstanceWorkItemId using SOQL
**/
public Id getWorkItemId(Id targetObjectId)
{
Id retVal = null;
for(ProcessInstanceWorkitem workItem : [Select p.Id from ProcessInstanceWorkitem p
where p.ProcessInstance.TargetObjectId =: targetObjectId])
{
retVal = workItem.Id;
}
return retVal;
}
/**
* This method will Approve the AprovalProcessObj__c
**/
public void approveRecord(AprovalProcessObj__c apo)
{
Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
req.setComments('使用Trigger批准。');
req.setAction('Approve');
req.setNextApproverIds(new Id[] {apo.Next_Approver__c});
Id workItemId = getWorkItemId(apo.id);
if(workItemId == null)
{
apo.addError('Error Occured in Trigger(approveRecord)');
}
else
{
req.setWorkitemId(workItemId);
// Submit the request for approval
Approval.ProcessResult result = Approval.process(req);
}
}
/**
* This method will Reject the AprovalProcessObj__c
**/
public void rejectRecord(AprovalProcessObj__c apo)
{
Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
req.setComments('使用Trigger拒绝。');
req.setAction('Reject');
Id workItemId = getWorkItemId(apo.id);
if(workItemId == null)
{
apo.addError('Error Occured in Trigger(rejectRecord)');
}
else
{
req.setWorkitemId(workItemId);
// Submit the request for approval
Approval.ProcessResult result = Approval.process(req);
}
}
}
Copyright © 乔木船长
个人主页:乔木船长
欢迎转发点评和指正!
本文详细解析了Salesforce中审批流程的核心组件,包括处理定义、流程实例、步骤、节点、请求和历史,以及审批流程触发器的代码实现,帮助读者深入了解审批流程的工作原理。
1096





