使用代码处理业务流程

通过业务流程流,可以创建更高效、更简化的销售、服务和其他业务流程。 它通过在实体窗体顶部放置特殊控件来创建业务流程的可视化效果。 用户可在引导下完成销售、营销或服务流程的各个阶段,直到完成。 每个流程支持多个阶段和步骤。 您可以添加或删除步骤,各个阶段顺序,或者向业务流程流添加新实体。

不同的业务流程实例可以针对同一实体记录同时运行。 用户可以在并行业务流程实例之间切换,并在流程的当前阶段恢复工作。

本主题提供有关如何以编程方式处理业务流程的信息。

注释

您不必编写代码来处理业务流程。 有关使用 Dynamics 365 Customer Engagement 客户端 (UI) 创建和管理业务流程流的信息,请参阅业务流程流概述

业务流程的先决条件

自定义实体和具有更新 UI 窗体的实体可以参与业务流程。 更新的 UI 实体的 IsAIRUpdated 属性设置为 true

若要为业务流程流启用实体,请将 IsBusinessProcessEnabled 属性设置为 true

重要

为业务流程流启用实体是单向过程。 该过程不能逆转。

定义业务流程

使用可视业务流程设计器来定义业务流程。 详细信息:创建业务流程

默认情况下,业务流程记录在 Draft 阶段创建。

业务流程定义存储在 workflow 实体中,业务流程的阶段信息存储在 processstage 实体中。

激活业务流程

使用流程流之前,必须激活它。 若要激活它,您必须具有 Workflow 实体的 prvActivateBusinessProcessFlow 权限。 使用 UpdateRequest 消息可将 Workflow 实体记录的状态设置为 Activated。 详细信息:使用 Update 执行专门操作

注释

您还可以使用业务流程设计器来激活业务流程。

业务流程实体

通过更改相应的 Workflow 实体记录的状态或使用业务流程流设计器激活业务流程流定义后,将自动创建具有以下名称的自定义实体以存储激活的业务流程流实例:“<activesolutionprefix>_<uniquename>”,其中 uniquename 是从您指定的名称派生的。

例如,如果您将“我的自定义 BPF”指定为业务流程定义的名称并对活动解决方案使用默认发布服务器(新),则为存储流程实例创建的自定义实体的名称将为“new_mycustombpf”。

如果业务流程流定义的 uniquename 值不可用,例如,如果业务流程流是作为早期版本的解决方案的一部分导入的,则自定义实体的默认名称将为 “<activesolutionprefix>_bpf_<GUID_BPF_Definition>”:

重要

Dynamics 365 中提供的示例业务流程流记录使用系统实体来存储相应的业务流程流实例记录。 一些示例业务流程流实体记录是 OpportunitySalesProcess 实体LeadToOpportunitySalesProcess 实体

但是,您创建的所有新业务流程都将使用自定义实体存储其实例记录,如前面所述。

您可以使用以下任一方法检索业务流程实体的名称:

  • 使用 UI:使用自定义 UI 浏览到业务流程流实体:

    BPF 实体名称。

  • 使用 Web API:使用以下请求:

    请求

    GET [Organization URI]/api/data/v9.1/workflows?$filter=name eq 'My Custom BPF'&$select=uniquename HTTP/1.1
    

    响应

    {  
    "@odata.context":"[Organization URI]/api/data/v9.1/$metadata#workflows(uniquename)",
    "value":[  
         {  
             "@odata.etag":"W/\"1084677\"",
             "uniquename":"new_mycustombpf",
             "workflowid":"2669927e-8ad6-4f95-8a9a-f1008af6956f"
         }
      ]
    }
    
    
  • 使用组织服务:使用以下代码示例:

    QueryExpression query = new QueryExpression
    {
        EntityName = "workflow",
        ColumnSet = new ColumnSet("uniquename"),
        Criteria = new FilterExpression
        {
            Conditions =
            {
                new ConditionExpression
                {
                    AttributeName = "name",
                    Operator = ConditionOperator.Equal,
                    Values = { "My Custom BPF" }
                }
            }
        }
    };
    Workflow Bpf = (Workflow)_serviceProxy.RetrieveMultiple(query).Entities[0]; 
    
    

注释

对于业务流程实体,IsBPFEntity 属性为 true。 通过运行以下 Web API 请求,可以在实例中检索所有业务流程实体:

GET [Organization URI]/api/data/v9.1/EntityDefinitions?$select=SchemaName,LogicalName,DisplayName&$filter=IsBPFEntity eq true HTTP/1.1

管理业务流程的安全性

激活业务流程流时自动创建来存储业务流程流实例的自定义实体遵守标准安全模型,正如 Customer Engagement 中的其他任何自定义实体。 这意味着为这些实体授予的权限定义业务流程的用户的运行时权限。

自定义业务流程实体的作用范围为组织。 此实体中的常规创建、检索、更新和删除特权定义了用户根据分配到的角色所拥有的权限。 默认情况下,在业务流程自定义实体创建后,只有系统管理员系统定制员的安全角色拥有对它的访问权限,对于其他安全角色,必须根据需要显式授予新业务流程实体(例如,我的自定义 BPF)的权限。

BPF 特权。

创建、检索、更新和删除业务流程实体记录(流程实例)

激活业务流程定义时自动创建的自定义实体存储该业务流程定义的所有流程实例。 自定义实体支持使用 Web API 和 CRM 2011 终结点以标准编程方式创建和管理记录(流程实例)。

重要

仅支持通过 UI(客户端)或以编程方式使用本节的可用信息切换到实体记录的其他流程实例。 无法再使用 SetProcess 消息(SetProcess 操作SetProcessRequest)以编程方式切换目标实体记录的流程(将其他业务流程流设置为活动的流程实例)。

让我们思考以下示例,其中包含具有以下 3 个阶段的跨实体业务流程“我的自定义 BPF”:S1:客户、S2:客户以及 S3:联系人。

示例 BPF。

检索业务流程实体的所有记录(实例)

如果业务流程实体的名称为“new_mycustombpf”,请使用以下查询检索业务流程实体的所有记录(流程实例):

GET [Organization URI]/api/data/v9.1/new_mycustombpfs HTTP/1.1 

此时,您可能无法在响应中获得任何实例,因为没有实例。 在本主题后面创建业务流程定义的实例后运行此请求。

注释

要了解如何检索业务流程实体的名称,请参阅前面一节业务流程实体

创建业务流程实体记录(流程实例)

如果要在不使用 UI 的情况下切换到实体记录的另一个业务流程,请以编程方式创建业务流程实体记录(流程实例)。

(!注意) 在统一界面中创建记录并且不希望有与记录关联的业务流程流时,创建一个用于调用 setActiveProcess 和传递空 processID (GUID) 的加载脚本。 代码示例 formcontext.data.process.setActiveProcess('00000000-0000-0000-0000-000000000000', (a)=>{​​alert("changed -- " + a)}​​)

要创建业务流程实体记录,您需要指定以下值:

  • 通过使用 @odata.bind 注释设置单值导航属性,将业务流程实体记录关联到主要实体记录。 要查找指向业务流程定义的主要实体记录的导航属性名称,请使用 CSDL $metadata 文档

  • 通过使用 @odata.bind 注释设置单值导航属性,将业务流程实体记录关联到业务流程定义中指定的有效阶段。 要查找指向业务流程定义的阶段记录的导航属性名称(通常为 activestageid),请使用 CSDL $metadata 文档

    此外,假设业务流程流定义的 ID 为 2669927e-8ad6-4f95-8a9a-f1008af6956f,您可以使用以下 Web API 请求检索有关业务流程流定义的所有阶段的信息:

    请求

    GET [Organization URI]/api/data/v9.1/processstages?$select=stagename&$filter=processid/workflowid eq 2669927e-8ad6-4f95-8a9a-f1008af6956f HTTP/1.1
    

    响应

    {
        "@odata.context": "[Organization URI]/api/data/v9.1/$metadata#processstages(stagename)",
        "value": [
            {
                "@odata.etag": "W/\"858240\"",
                "stagename": "S1",
                "processstageid": "9a9185f5-b75b-4bbb-9c2b-a6626683b99b"
            },
            {
                "@odata.etag": "W/\"858239\"",
                "stagename": "S3",
                "processstageid": "a107e2fd-7543-4c1a-b6b4-b8060ecb1a1a"
            },
            {
                "@odata.etag": "W/\"858238\"",
                "stagename": "S2",
                "processstageid": "19a11fc0-3398-4214-8522-cb2a97f66e4b"
            }
        ]
    }
    

接下来,使用以下请求为客户记录 (ID=a176be9e-9a68-e711-80e7-00155d41e206) 创建业务流程流定义的实例,并将活动阶段设置为流程实例的第一个阶段 S1 (ID=9a9185f5-b75b-4bbb-9c2b-a6626683b99b):

请求

POST [Organization URI]/api/data/v9.1/new_mycustombpfs HTTP/1.1 
Content-Type: application/json; charset=utf-8 
OData-MaxVersion: 4.0 
OData-Version: 4.0 
Accept: application/json 

{
    "bpf_accountid@odata.bind": "/accounts(a176be9e-9a68-e711-80e7-00155d41e206)",
    "activestageid@odata.bind": "/processstages(9a9185f5-b75b-4bbb-9c2b-a6626683b99b)"    
}

响应

HTTP/1.1 204 No Content
OData-Version: 4.0
OData-EntityId: [Organization URI]/api/data/v9.1/new_mycustombpfs(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)

请注意,如果要创建业务流程流定义的实例,并将活动阶段设置为除第一阶段之外的阶段,您还必须在请求中提供 traversedpath。 遍历路径是以逗号分隔的流程阶段 ID 字符串,表示业务流程实例的访问阶段。 以下请求为客户记录 (ID=679b2464-71b5-e711-80f5-00155d513100) 创建实例,活动阶段设置为第二阶段 S2 (ID=19a11fc0-3398-4214-8522-cb2a97f66e4b)。

POST [Organization URI]/api/data/v9.1/new_mycustombpfs HTTP/1.1 
Content-Type: application/json; charset=utf-8 
OData-MaxVersion: 4.0 
OData-Version: 4.0 
Accept: application/json 

{
    "bpf_accountid@odata.bind": "/accounts(679b2464-71b5-e711-80f5-00155d513100)",
    "activestageid@odata.bind": "/processstages(19a11fc0-3398-4214-8522-cb2a97f66e4b)",
    "traversedpath":"9a9185f5-b75b-4bbb-9c2b-a6626683b99b,19a11fc0-3398-4214-8522-cb2a97f66e4b"   
}

更新业务流程实体记录(流程实例)

您可以更新流程实例以移至下一个或上一个阶段,放弃、重新激活或完成流程实例。

阶段导航

要导航到其他阶段,您需要更新流程实例记录以更改其活动阶段 ID,并相应地更新遍历的路径。 请注意,在更新业务流程实例时,您只能移到下一个或上一个阶段。

要执行阶段导航,将需要待更新的业务流程实例的 ID。 要检索业务流程的所有实例,请参阅先前的检索业务流程实体的所有记录(实例)

假设您要更新的流程实例的 ID 为 dc2ab599-306d-e811-80ff-00155d513100,请使用以下请求将活动阶段从 S1 更新为 S2:

PATCH [Organization URI]/api/data/v9.1/new_mycustombpfs(dc2ab599-306d-e811-80ff-00155d513100) HTTP/1.1
Content-Type: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0

{
    "activestageid@odata.bind": "/processstages(19a11fc0-3398-4214-8522-cb2a97f66e4b)",
    "traversedpath": "9a9185f5-b75b-4bbb-9c2b-a6626683b99b,19a11fc0-3398-4214-8522-cb2a97f66e4b"
}

更改流程实例的状态:中止、重新激活或完成

流程实例可以具有以下状态之一:活动已完成已中止。 状态由流程实例记录中的以下属性确定:

  • statecode:显示流程实例的状态。

    价值 Label
    0 主动
    1 未激活
  • statuscode:显示有关流程实例状态的信息。

    价值 Label
    1 主动
    2 已完成
    3 已中止

因此,要中止流程实例,请使用以下请求适当地设置 statecodestatuscode 值:

PATCH [Organization URI]/api/data/v9.1/new_mycustombpfs(dc2ab599-306d-e811-80ff-00155d513100) HTTP/1.1   
Content-Type: application/json   
OData-MaxVersion: 4.0   
OData-Version: 4.0 
  
{ 
    "statecode" : "1", 
    "statuscode": "3" 
}

注释

可以在任何阶段中止流程实例。

同样,要重新激活流程实例,请将上述代码中的 statecodestatuscode 值分别替换为 01

最后,要将流程实例状态设置为已完成,这只能在流程实例的最后阶段进行,请将上述代码中的 statecodestatuscode 值分别替换为 02

跨实体导航

对于本例中的跨实体导航,必须将流程实例的活动阶段设置为最后一个阶段 S3 (ID=a107e2fd-7543-4c1a-b6b4-b8060ecb1a1a),相应地更新遍历的路径,并设置联系人记录作为业务流程定义的主要实体记录。

PATCH [Organization URI]/api/data/v9.1/new_mycustombpfs(dc2ab599-306d-e811-80ff-00155d513100) HTTP/1.1   
Content-Type: application/json   
OData-MaxVersion: 4.0   
OData-Version: 4.0 
  
{
    "activestageid@odata.bind": "/processstages(a107e2fd-7543-4c1a-b6b4-b8060ecb1a1a)",
    "traversedpath":"9a9185f5-b75b-4bbb-9c2b-a6626683b99b,19a11fc0-3398-4214-8522-cb2a97f66e4b,a107e2fd-7543-4c1a-b6b4-b8060ecb1a1a",
    "bpf_contactid@odata.bind": "/contacts(0e3f10b0-da33-e811-80fc-00155d513100)"
}

删除业务流程实体记录(流程实例)

使用以下 Web API 请求:

请求

DELETE [Organization URI]/api/data/v9.1/new_mycustombpfs(dc2ab599-306d-e811-80ff-00155d513100) HTTP/1.1

响应

如果记录存在,您将获得状态为 204 的正常响应,指示删除成功。 如果未找到实体,您将收到状态 404 的响应。

使用 RetrieveProcessInstances 和 RetrieveActivePath 消息

使用 RetrieveProcessInstances 消息(RetrieveActivePath 函数RetrieveProcessInstancesRequest)检索所有业务流程定义中的实体记录的所有业务流程流实例。 为某个实体返回的业务流程实例基于该实例的 modifiedon 属性排序。 例如,最近修改的业务流程流实例将为返回的集合中的第一条记录。 最近修改的业务流程实例是 UI 中实体记录的活动实例。

作为使用 RetrieveProcessInstances 消息的结果,为实体记录返回的每个业务流程实例记录都将活动阶段的 ID 存储在可用于查找活动阶段的 processstageid 属性中,然后移至上一或下一阶段。 为此,首先需要使用 RetrieveActivePath 消息查找业务流程流实例的活动路径以及流程实例中可用的阶段(RetrieveActivePath 函数RetrieveActivePathRequest)。

获得业务流程实例的活动阶段和活动路径信息之后,可使用这些信息移到活动路径中的上一阶段或下一阶段。 阶段的前进导航必须按顺序执行,即,只应前进到活动路径中的下一阶段。

有关代码演示使用组织服务的这两种方法和阶段导航的用法的完整示例,请参阅示例:处理业务流程

创建实体记录时应用业务流程

本节提供有关将业务流程流自动应用于 Customer Engagement 中新建的实体记录的默认行为的信息,以及有关如何将其替代来为新实体记录应用您选择的业务流程流的信息。

默认情况下,对于为其定义了多个业务流程的实体,系统使用以下多步骤逻辑为新实体记录应用业务流程:

  1. 根据业务流程流定义记录的 Workflow.PrimaryEntity 属性,确定适用于新实体记录的所有业务流程流。
  2. 识别当前用户可访问的业务流程定义。 有关如何确定和管理对业务流程的访问的信息,请参阅本主题前面的管理业务流程的安全性
  3. 系统中的所有业务流程定义均遵守按实体的全局顺序。 业务流程的顺序存储在 Workflow.ProcessOrder 属性中。 将根据此顺序存储实体的业务流程定义,并选择顺序值最小的定义。
  4. 最后,如果实体记录是从业务应用程序(应用程序模块)创建的,则选择要自动应用于新实体记录的业务流程时,将多应用一级筛选。 在应用程序中工作时,用户只能访问根据为其分派的业务应用程序安全角色可访问的相关实体、业务流程、视图和窗体。
    • 如果业务应用程序中不包含任何业务流程,则按照截止步骤 3 的说明应用业务流程。
    • 如果业务应用程序有一个或多个业务流程,则仅应用该应用程序中存在的业务流程。 在这种情况下,用户在业务应用程序上下文中工作时,将把筛选步骤 3 中的业务流程列表进一步筛选到属于业务应用程序且在应用程序模块中存在的业务流程,并根据流程顺序排序。
    • 如果业务应用程序中没有实体的可用业务流程或用户可访问的业务流程,则不为新实体记录应用业务流程。

可以覆盖自动应用于新实体记录的业务流程的默认逻辑。 为此,请在创建新实体记录时将实体的 ProcessId 属性设置为以下值之一:

  • 设置为 Guid.Empty 以跳过为新实体记录设置业务流程。 如果在批量创建实体记录,但不希望为其应用业务流程流,则可能需要这样做。
  • 将其设置为特定业务流程实体(作为实体引用)。 在这种情况下,系统将应用指定的业务流程,而不是应用默认逻辑。

如果在创建新实体记录时未设置 ProcessId 属性的值,系统将应用前面介绍的默认逻辑。

注释

仅以编程方式支持覆盖自动应用于新实体记录的业务流程的默认逻辑。 不能使用 UI 替代。

已经弃用为业务流程流启用的实体中与旧流程相关的属性(ProcessIdStageIdTraversedPath)以及 setProcess 客户端 API。 处理目标实体记录的这些与旧流程相关的属性或使用旧 setProcess 客户端 API,不保证业务流程流状态一致,因此不是支持的场景。 建议的方法是使用业务流程实体的属性,如前面在创建、检索、更新和删除业务流程实体记录(流程实例)一节中介绍

唯一的例外是以编程方式修改 ProcessId 属性,同时创建实体记录以将业务流程流的默认应用程序覆盖到新记录,如上一节所述:在创建实体记录时应用业务流程流

客户端对业务流程的可编程性支持

使用 Dynamics 365,可以使用客户端对象与窗体脚本中的业务流程流进行交互。 只要为记录应用流程,或状态更改为 ActiveFinishedAborted,业务流程都将触发客户端事件。 详细信息:formContext.data.process(客户端 API 引用)

流程、阶段和步骤的最大数量

每个实体的最大激活业务流程流数量默认值为 10。 可以使用 Organization.MaximumActiveBusinessProcessFlowsAllowedPerEntity 属性指定其他值。 但是,如果该值大于 10,当您进行流程切换或打开某个有分派业务流程的记录的时候,会发现系统性能下降。 如果该流程涉及到多个实体,这种现象会更明显。

不能自定义下列设置:

  • 每个实体的流程的最大阶段数量为 30。

  • 每个阶段的最大步骤数量为 30。

  • 可参与流程流的最大实体数量为 5。

另请参阅