流程管理

介绍

可以利用OTRS系统定制流程(工作流)模型。基本思路在于定义可重复执行的流程,并将工作内容指派给不同的人员,同时确保流程按照预期进入不同阶段并最终顺利完成。

流程示例

让我们看一个例子,更易于阐述流程管理。我们将定义一个订书流程:

记录需求

在生成订单之前,雇员对书籍的需求将被记录。下列书籍是我们示例中所需要的:

标题: Prozessmanagement für Dummies
作者: Thilo Knuppertz
ISBN: 3527703713
                

经理审批

部门经理需要确认需求。若经理拒绝,需要记录决定原因。若同意,流程将会跳转到采购部。

采购部处理

现在采购人员需要找出如何以最好的条件购买所需书籍。若书籍缺货,需要在工单中进行记录。如果成功下单,将需要记录供应商、售价与交货时间。

收发室处理

这批货物将到达公司。进货部门负责检查货物,并记录货品到达日期。接着员工将被告知他们的订单已经到达,并已准备好进行接收。

实施示例

假设在这个工作流中,工单可以像随同文档一样接收变更记录,那么我们就有了很清晰的工单处理流程图。

通过示例流程分析,我们可以确定下列需要的条目:

  • 数据记录功能,我们称其为Activity Dialogs (活动对话框)

  • 根据数据变化自动反应的检查,我们称之为Transitions(转换)

  • 在流程单成功转换后,对流程工单的变更,我们称之为 Transition Actions 转换操作

我们同样还需要一些不那么复杂的额外项:

  • 可能存在不止一个活动对话框(Activity Dialog)。在示例中,经理必须在"Approve 同意" 与 "Deny 拒绝"中做出决定。我们称之为Activity 活动

现在,结合活动(Activities)、活动对话框(Activity Dialogs)、转换(Transitions)与转换操作(Transition Actions),我们可以对示例的各个独立步骤进行建模。现在还缺少为每个工作流步骤设置具体顺序。我们称之为Process 流程。为了能在之后指代所有这些实体,我们将分配给他们括号中的缩写。这个缩写基于内部识别机制EntityID。

EntityID以1~2个字母开头(取决于流程组件或实体),接着跟随连续编号,例如:

  • 流程: 'P1', 'P2' ... 'Pn'.

  • 活动: 'A1', 'A2' ... 'An'.

  • 活动对话框: 'AD1', 'AD2' ... 'ADn'.

  • Transition: 'T1', 'T2' ... 'Tn'.

  • 转换操作: 'TA1', 'TA2' ... 'TAn'.

在新建流程和相关内容之前,需要提前准备好系统,我们需要定义一些队列、用户和动态字段,还需要在系统配置中设置一些参数。

创建如下队列:

  • 管理

  • 员工

  • 采购

  • 邮局

创建如下用户:

  • 经理

  • 员工

创建如下动态字段:

  • 标题

    标签标题
    类型文本
    对象工单
  • 作者

    标签作者
    类型文本
    对象工单
  • ISBN

    标签ISBN
    类型文本
    对象工单
  • 状态

    标签状态
    类型下拉选项框
    对象工单
    可能的值
    • 审批

    • 审批拒绝

    • 通过审批

    • 采购拒绝

    • 生成订单

    • 货品收到

    注意:需要在创建动态字段的“键”和“值”时尽可能使用最接近的值。

  • 供应商

    标签供应商
    类型文本
    对象工单
  • 价格

    标签价格
    类型文本
    对象工单
  • 交货日期

    标签交货日期
    类型日期
    对象工单
  • 收货日期

    标签收货的日期
    类型日期
    对象工单

在系统配置(SysConfig)中设置:

  • 'Ticket::Responsible': 是

  • 'Ticket::Frontend::AgentTicketZoom###ProcessWidgetDynamicFieldGroups':

    键:值:
    书箱标题, 作者, ISBN
    一般状态
    订单价格, 供应商, 交货日期
    运输收货日期
  • 'Ticket::Frontend::AgentTicketZoom###ProcessWidgetDynamicField':

    键:值:
    作者1
    收货日期1
    交货日期1
    ISBN1
    价格1
    状态1
    供应商1
    标题1

现在我们可以开始真正的流程管理配置了。下一步,我们将定义所需的独立实体。

流程(作为容器)

创建一个新流程,需要点击管理员面板中系统管理的"Process Management 流程管理",我们会进入流程管理概览屏幕。在创建流程后,我们就可以创建其他全部实体(或流程组件)。

注意

一个流程中所定义的Activitiy(活动)、Activity Dialog(活动对话框)、Transition(转换) 与 Transition Action(转换操作),都可以被系统中的所有流程使用。

图 5.7. OTRS系统管理屏幕 - 系统管理

OTRS系统管理屏幕 - 系统管理


点击左侧操作框的“创建新的流程”按钮。

图 5.8. 创建新的流程按钮

创建新的流程按钮


填写流程信息、设置流程名与描述,我们在完成所有配置任务之前,我们先把流程状态设为“非活动”。

图 5.9. 添加新流程

添加新流程


活动对话框

在流程管理概览屏幕点击新建的流程名称,然后在“可用的流程元素”中点击“活动对话框”(点击会展开活动对话框选项,并收起其它具有可折叠效果的选项),再点击“创建新的活动对话框”。

图 5.10. 创建新的活动对话框按钮

创建新的活动对话框按钮


在打开的弹出屏幕中填写“活动对话框名称”和“描述(简短)”相同内容,本例中我们将其它字段都保持默认值,要给活动对话框分配字段,仅需从“可用的字段”池中拖动必填字段,并放到“分配的字段”池中即可。“分配的字段”池中的字段顺序为将字段放进去的先后顺序,可通过拖放操作进行字段重新排序。

图 5.11. 添加新的活动对话框

添加新的活动对话框


将选择的字段拖入"分配的字段"池后,会弹出另一个屏幕,显示该字段详细信息,保留默认选项即可,接着将通信通道字段的信件字段设置为 "内部",且不选中“是否对客户可见”。

图 5.12. 编辑字段详细信息(信件)

编辑字段详细信息(信件)


在所有字段都分配好之后,点击主弹出屏幕的提交按钮,保存修改记录。

本例中,我们将使用信件字段来记录备注,但是可以用另外一个选项创建一个多行文本类型的动态字段,在下面的行中上述剩余的字段是我们之前定义好的动态字段。

请注意本屏幕中的所有动态字段都有“DynamicField_”前缀如“DynamicField_Title”,不要与工单标题的字段“Title(标题)”搞混淆了。

创建如下活动对话框:

  • "记录需求" (AD1)

    此活动对话框包含了订单所需的所有数据字段(标题、作者与ISBN号),以及一个标识审批状态的字段“审批”。

  • “审批拒绝” (AD2)

    此活动对话框拥有一个用于注释的字段 (信件)与一个选择“审批拒绝”状态的字段“审批拒绝”。

  • “通过审批” (AD3)

    只需要一个状态字段,选项为“通过审批”。

  • “采购拒绝” (AD4)

    此活动对话框设计来拒绝一笔无效的采购单(书籍缺货)。这里同样需要一个注释字段与一个状态字段选项“采购拒绝”。

  • “生成订单” (AD5)

    活动对话框中包含了采购涉及的供应商、价格与发货日期字段以及状态字段选项 “生成订单”。

  • “货品收到” (AD6)

    此活动需要为收发室添加一个收到日期的字段,还需要一个状态字段选项“货品收到”。

为了限制每个活动对话框的状态字段值,我们需要在Kernel/Config.pm或一个新的Perl文件Kernel/Config/Files中添加一些ACL。

    $Self->{TicketAcl}->{'P1-AD1-1'} = {
        Properties => {
            Process => {
                ActivityDialogEntityID => ['AD1'],
            },
        },
        Possible => {
            Ticket => {
                DynamicField_Status => ['Approval'],
            },
        },
    };

    $Self->{TicketAcl}->{'P1-AD2-1'} = {
        Properties => {
            Process => {
                ActivityDialogEntityID => ['AD2'],
            },
        },
        Possible => {
            Ticket => {
                DynamicField_Status => ['Approval denied'],
            },
        },
    };

    $Self->{TicketAcl}->{'P1-AD3-1'} = {
        Properties => {
            Process => {
                ActivityDialogEntityID => ['AD3'],
            },
        },
        Possible => {
            Ticket => {
                DynamicField_Status => ['Approved'],
            },
        },
    };

    $Self->{TicketAcl}->{'P1-AD4-1'} = {
        Properties => {
            Process => {
                ActivityDialogEntityID => ['AD4'],
            },
        },
        Possible => {
            Ticket => {
                DynamicField_Status => ['Order denied'],
            },
        },
    };

    $Self->{TicketAcl}->{'P1-AD5-1'} = {
        Properties => {
            Process => {
                ActivityDialogEntityID => ['AD5'],
            },
        },
        Possible => {
            Ticket => {
                DynamicField_Status => ['Order placed'],
            },
        },
    };

    $Self->{TicketAcl}->{'P1-AD6-1'} = {
        Properties => {
            Process => {
                ActivityDialogEntityID => ['AD6'],
            },
        },
        Possible => {
            Ticket => {
                DynamicField_Status => ['Shipment received'],
            },
        },
    };
                    

转换

在“可用的流程元素”中点击“转换”, 接着点击“创建新的转换”。

图 5.13. 创建新的转换按钮

创建新的转换按钮


在弹出屏幕填写“转换名称”,接着我们需要配置条件选项,本例中只需要设置一个条件和一个字段,可以设置链接类型为“与”以及字段匹配类型值为“字符串”。

图 5.14. 创建新转换

创建新转换


所有条件设置好后,点击提交按钮,保存结果。

创建如下转换:

  • “审批” (T1)

    用于检查状态字段是否被设置为“审批”的转换。

  • “审批拒绝” (T2)

    用于检查状态字段是否被设置为“审批拒绝”的转换。

  • “通过审批” (T3)

    用于检查状态字段是否被设置为“通过审批”的转换。

  • “采购拒绝” (T4)

    用于检查状态字段是否被设置为“采购拒绝”的转换。

  • “生成订单” (T5)

    用于检查状态字段是否被设置为“生成订单”的转换。

  • “货品收到” (T6)

    用于检查状态字段是否被设置为“货品收到”的转换。

转换操作

点击“可用的流程元素”中的“转换操作”,接着点击“创建新的转换操作”。

图 5.15. 创建新的转换操作按钮

创建新的转换操作按钮


在弹出屏幕填写“转换操作名称”和“转换操作模块”,然后添加必填的和可选的参数名和参数值。

所有的转换操作模块位于文件Kernel/System/ProcessManagement/TransitionAction中,下面是本版本中捆绑的转换操作清单:

  • DynamicFieldSet动态字段设置

  • TicketArticleCreate工单信件创建

  • 工单创建

  • TicketCustomerSet工单客户设置

  • TicketLockSet工单锁定设置

  • TicketOwnerSet工单所有者设置

  • TicketQueueSet工单队列设置

  • TicketResponsibleSet工单负责人设置

  • TicketServiceSet工单服务设置

  • TicketSLASet工单SLA设置

  • TicketStateSet工单状态设置

  • TicketTitleSet工单标题设置

  • TicketTypeSet工单类型设置

每个模块都拥有其独立与不同的参数。请查阅module documentation 模块文档来了解所有必填与可选参数。

注意

从OTRS 4.0.1开始,参数不再强制使用固定值,而是通过格式<OTRS_Ticket_property>从原始工单继承。

从OTRS 4.0.6开始支持格式<OTRS_TICKET_property>,老格式仍然可以使用,但是会在将来的版本中废弃。

图 5.16. 创建新的转换操作

创建新的转换操作


当所有参数与数值都配置好后,点击提交按钮保存变更。

新建如下转换操作:

  • “将工单移入‘管理’队列” (TA1)

    此动作预计在转换“审批” (T1)应用后执行。

  • “变更工单负责人为‘经理’ ” (TA2)

    此动作在转换“审批” (T1)应用后执行。

  • “移动流程工单到‘员工’队列” (TA3)

    当遇到如下情况时执行:

    • 应用了转换“审批拒绝” (T2)。

    • 应用了转换 “采购拒绝” (T4)。

    • 应用了转换 “货品收到” (T6)。

  • “变更工单负责人为‘员工’” (TA4)

    当遇到如下情况时执行:

    • 应用了转换“审批拒绝” (T2)。

    • 应用了转换 “采购拒绝” (T4)。

    • 应用了转换 “货品收到” (T6)。

  • “将工单转入‘采购’队列” (TA5)

    当应用了转换 “通过审批” (T3)时执行。

  • “移动工单至‘邮局’队列” (TA6)

    当应用了“生成订单” (T5)时执行。

  • “工单成功关闭” (TA7)

    当遇到如下情况时执行:

    • 应用了转换“货品收到” (T6)。

  • “工单失败关闭” (TA8)

    当遇到如下情况时执行:

    • 应用了转换“审批拒绝” (T2)。

    • 应用了转换 “采购拒绝” (T4)。

正如你所见,相同的转换操作会在很多地方被执行。因此设计允许转换操作与转换自由连接,是为了更好的复用资源。

活动

我们选择将活动(Activities)看作一个篮子,这个篮子可以包含一个或多个活动对话框(Activity Dialogs)。

点击“可用的流程元素”中的“活动”,接着点击“创建新活动”。

图 5.17. 创建新活动按钮

创建新活动按钮


在打开的弹出屏幕中填写“活动名称”,然后仅需从“可用的活动对话框”池中拖动需要的活动对话框,并放到“分配的活动对话框”池中即可。这些对话框会在工单详情屏幕按本屏幕定义的从上到下、从左到右的顺序显示出来。

在第一个活动中这个顺序特别重要,因为流程开始后唯一显示的就是这个活动的第一个活动对话框。

创建下列活动:

  • “记录需求” (A1)

    包含活动对话框“记录需求” (AD1)

  • “审批” (A2)

    包含活动对话框“审批拒绝” (AD2)和“通过审批” (AD3)

  • “订单” (A3)

    包含活动对话框“采购拒绝” (AD4)与“生成订单” (AD5)

  • “即将到达” (A4)

    包含活动对话框“货品收到” (AD6)

  • “流程结束” (A5): 这是一个没有活动对话框的活动。它需要被设置在“审批拒绝”、“采购拒绝”或者“货品收到”之后,代表流程结束。

现在我们可以清晰地看到,活动是一个流程工单精确定义的状态。在转换成功后,流程工单会从一个活动移动到另外一个。

书籍采购流程路径

让我们用拼图所缺失的最后一块来结束我们的示例-将流程作为流记录器。在我们的例子中,就是完整的订购工作流。其他流程可能还有办公用品订购或其他完全不同的流程。

此流程有一个起始点,它包括了初始活动和初始活动对话框。对于任何新书采购,初始活动对话框(第一个活动的第一个活动对话框)是最先显示的。如果这个活动完成并保存,流程工单将被创建并可以根据配置好的工作流进行处理。

流程中还包含了流程工单在流程中如何移动的方向。我们称之为“路径”。它由初始活动、一个或多个转换(可能包含转换操作)、以及其他活动组成。

假设该活动已经指派了相关的活动对话框,将其从折叠区域(屏幕的左侧部分)拖放到画布区域(在流程信息下面)。请注意,流程起始(绿色圆圈)会自动放置一个到该活动的箭头。(这是第一个活动,并且其第一个活动对话框会在流程开始后在屏幕第一个显示)。

图 5.18. 将第一个活动拖放到画布中

将第一个活动拖放到画布中


下一步,将另一个活动也拖放到画布中。现在画布中我们有了两个活动。第一个活动连接到起始点,第二个活动还没有连接。你可以将鼠标移动到活动上,会显示它们自己的活动对话框。

图 5.19. 拖动第二个活动到画布中

拖动第二个活动到画布中


接下来让我们在这两个活动间创建“路径”(连接),创建路径需要使用转换。在折叠区域点击“转换”并拖动一个转换到第一个活动里面放下。注意活动变化了颜色,表示附上了转换。转换一放下,转换箭头的终点就放置在邻近流程的起始点位置。拖动转换的箭头终点到另一活动里面来创建这两个活动的连接。

图 5.20. 拖放一个转换到画布上

拖放一个转换到画布上


现在操作之间的“路径”已经定义好了,接下来我们需要分配转换操作到这个转换上,在画布中双击转换标签,这会弹出新屏幕。

图 5.21. 使用转换连接活动

使用转换连接活动


从‘可用的转换操作’池中拖动所需的转换活动,并将其放置在‘分配的转换操作’池中,点击提交按钮。

图 5.22. 分配转换操作

分配转换操作


接着回到流程编辑主屏幕,点击画布下的保存按钮,保存所有其他的修改。

添加下列活动、转换和转换操作以完成“路径”:

记录需求直到“批准”

  • 起始点:活动“记录需求” (A1)

  • 可能的转换:“审批” (T1)

    • 如果这个活动的条件满足,该工单将移动到活动“审批” (A2)

    • 此外,还会执行下列的转换操作:

      • “将工单移入‘管理’队列” (TA1)

      • “变更工单负责人为‘经理’ ” (TA2)

活动:“记录需求” (A1)是流程工单预定义步骤,以确认转换:“审批” (T1)的可能性。如果适用,工单将移动到下一个活动:“审批” (A2),并且执行转换操作“移动到‘管理’队列” (TA1)和“变更工单负责人为‘经理’ (TA2)。在活动“审批” (A2)中,活动对话框“审批拒绝” (AD2) 和“通过审批” (AD3) 可用。

审批

  • 起始点:活动“审批” (A2)

  • 可能的转换:

    • “审批拒绝” (T2)

      • 如果匹配这个,流程工单就移动到活动“流程结束” (A5)。

      • 此外,还会执行下列的转换操作:

        • “移动流程工单到‘员工’队列” (TA3)

        • “变更工单负责人为‘员工’” (TA4)

        • “工单失败关闭” (TA8)

    • “通过审批” (T3)

      • 如果匹配这个,流程工单就移动到活动“订购” (A3)。

      • 此外,还会执行下面的转换操作::

        • “将工单转入‘采购’队列” (TA5)

我们可以看到,定义流程工单的当前活动有一个或多个转换的可能性,转换有一个目标活动(和可能的一个或多个转换操作)。

订单

  • 起始点:活动“订购” (A3)

  • 可能的转换:

    • “采购拒绝” (T4)

      • 如果匹配这个,流程工单就移动到活动“流程结束” (A5)。

      • 此外,还会执行下列的转换操作:

        • “移动流程工单到‘员工’队列” (TA3)

        • “设置工单负责人为‘员工’” (TA4)

        • “工单失败关闭” (TA8)

    • “生成订单” (T5)

      • 如果匹配这个,流程工单就移动到活动“即将到达” (A4)。

      • 此外,还会执行下面的转换操作::

        • “移动工单至‘邮局’队列” (TA6)

即将到达

  • 起始点:活动“即将到达” (A4)

  • 可能的转换:

    • “货品收到” (T6)

      • 如果匹配这个,流程工单就移动到活动“流程结束” (A5)。

      • 此外,还会执行下列的转换操作:

        • “移动流程工单到‘员工’队列” (TA3)

        • “设置工单负责人为‘员工’” (TA4)

        • “工单成功关闭” (TA7)

书籍采购流程完整路径看上去就像这样:

图 5.23. 书籍采购完整的流程路径

书籍采购完整的流程路径


在完成流程路径后,请点击画布正文的“保存”按钮,然后再点击“同步所有流程”按钮。这将收集所有的流程信息到数据库并创建一个缓存文件(用Perl语言)。这个缓存文件就是实际的流程配置,系统将用它来创建或处理流程工单。

任何流程变更(通过GUI界面)都需要重新同步缓存文件,才可以确保将变更映射到系统。

也可以从一个YAML文件导入整个流程,但是在导入前,仍然需要创建每个流程需要的所有动态字段、用户、队列等等。

注意:如果流程需要使用ACL,这些ACL也需要手动设置好。

下面是书籍采购流程示例的完整YAML文件内容:

---
Activities:
  A1:
    ActivityDialogs:
      - AD1
    ChangeTime: 2012-11-23 14:49:22
    Config:
      ActivityDialog:
        1: AD1
    CreateTime: 2012-11-23 11:49:38
    EntityID: A1
    ID: 151
    Name: Recording the demand
  A2:
    ActivityDialogs:
      - AD2
      - AD3
    ChangeTime: 2012-12-13 00:55:12
    Config:
      ActivityDialog:
        1: AD2
        2: AD3
    CreateTime: 2012-11-23 11:50:11
    EntityID: A2
    ID: 152
    Name: Approval
  A3:
    ActivityDialogs:
      - AD4
      - AD5
    ChangeTime: 2012-11-23 18:12:14
    Config:
      ActivityDialog:
        1: AD4
        2: AD5
    CreateTime: 2012-11-23 11:50:35
    EntityID: A3
    ID: 153
    Name: Order
  A4:
    ActivityDialogs:
      - AD6
    ChangeTime: 2012-11-23 18:12:35
    Config:
      ActivityDialog:
        1: AD6
    CreateTime: 2012-11-23 11:51:00
    EntityID: A4
    ID: 154
    Name: Incoming
  A5:
    ActivityDialogs: []
    ChangeTime: 2012-11-23 11:51:33
    Config: {}
    CreateTime: 2012-11-23 11:51:33
    EntityID: A5
    ID: 155
    Name: Process complete
ActivityDialogs:
  AD1:
    ChangeTime: 2012-12-06 02:16:21
    Config:
      DescriptionLong: ''
      DescriptionShort: Recoding the demand
      FieldOrder:
        - DynamicField_Author
        - DynamicField_ISBN
        - DynamicField_Title
        - DynamicField_Status
      Fields:
        DynamicField_Author:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_ISBN:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Status:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Title:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
      Interface:
        - AgentInterface
      Permission: ''
      RequiredLock: 0
      SubmitAdviceText: ''
      SubmitButtonText: ''
    CreateTime: 2012-11-23 14:34:43
    EntityID: AD1
    ID: 154
    Name: Recording the demand
  AD2:
    ChangeTime: 2012-11-23 14:57:41
    Config:
      DescriptionLong: ''
      DescriptionShort: Approval denied
      FieldOrder:
        - Article
        - DynamicField_Status
      Fields:
        Article:
          Config:
            CommunicationChannel:  'Internal'
            IsVisibleForCustomer: '0'
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Status:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
      Interface:
        - AgentInterface
      Permission: ''
      RequiredLock: 0
      SubmitAdviceText: ''
      SubmitButtonText: Deny Request
    CreateTime: 2012-11-23 14:36:39
    EntityID: AD2
    ID: 155
    Name: Approval denied
  AD3:
    ChangeTime: 2012-12-14 03:14:23
    Config:
      DescriptionLong: ''
      DescriptionShort: Approved
      FieldOrder:
        - DynamicField_Status
      Fields:
        DynamicField_Status:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
      Interface:
        - AgentInterface
      Permission: ''
      RequiredLock: 0
      SubmitAdviceText: ''
      SubmitButtonText: Approve Request
    CreateTime: 2012-11-23 14:37:35
    EntityID: AD3
    ID: 156
    Name: Approved
  AD4:
    ChangeTime: 2012-11-23 14:58:52
    Config:
      DescriptionLong: ''
      DescriptionShort: Order rejected
      FieldOrder:
        - Article
        - DynamicField_Status
      Fields:
        Article:
          Config:
            CommunicationChannel:  'Internal'
            IsVisibleForCustomer: '0'
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Status:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
      Interface:
        - AgentInterface
      Permission: ''
      RequiredLock: 0
      SubmitAdviceText: ''
      SubmitButtonText: Reject Order
    CreateTime: 2012-11-23 14:38:48
    EntityID: AD4
    ID: 157
    Name: Order rejected
  AD5:
    ChangeTime: 2012-12-06 02:20:12
    Config:
      DescriptionLong: ''
      DescriptionShort: Order placed
      FieldOrder:
        - DynamicField_DeliveryDate
        - DynamicField_Price
        - DynamicField_Supplier
        - DynamicField_Status
      Fields:
        DynamicField_DeliveryDate:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Price:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Status:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Supplier:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
      Interface:
        - AgentInterface
      Permission: ''
      RequiredLock: 0
      SubmitAdviceText: ''
      SubmitButtonText: Place Order
    CreateTime: 2012-11-23 14:41:28
    EntityID: AD5
    ID: 158
    Name: Order placed
  AD6:
    ChangeTime: 2012-11-23 14:42:43
    Config:
      DescriptionLong: ''
      DescriptionShort: Shipment received
      FieldOrder:
        - DynamicField_DateOfReceipt
        - DynamicField_Status
      Fields:
        DynamicField_DateOfReceipt:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
        DynamicField_Status:
          DefaultValue: ''
          DescriptionLong: ''
          DescriptionShort: ''
          Display: 1
      Interface:
        - AgentInterface
      Permission: ''
      RequiredLock: 0
      SubmitAdviceText: ''
      SubmitButtonText: ''
    CreateTime: 2012-11-23 14:42:43
    EntityID: AD6
    ID: 159
    Name: Shipment received
Process:
  Activities:
    - A1
    - A2
    - A3
    - A4
    - A5
  ChangeTime: 2012-12-06 02:31:59
  Config:
    Description: The process to order a book
    Path:
      A1:
        T1:
          ActivityEntityID: A2
          TransitionAction:
            - TA2
            - TA1
      A2:
        T2:
          ActivityEntityID: A5
          TransitionAction:
            - TA3
            - TA4
            - TA8
        T3:
          ActivityEntityID: A3
          TransitionAction:
            - TA5
      A3:
        T4:
          ActivityEntityID: A5
          TransitionAction:
            - TA3
            - TA4
            - TA8
        T5:
          ActivityEntityID: A4
          TransitionAction:
            - TA6
      A4:
        T6:
          ActivityEntityID: A5
          TransitionAction:
            - TA3
            - TA4
            - TA7
      A5: {}
    StartActivity: A1
    StartActivityDialog: AD1
  CreateTime: 2012-11-23 11:45:12
  EntityID: P1
  ID: 94
  Layout:
    A1:
      left: 172
      top: 63
    A2:
      left: 402
      top: 156
    A3:
      left: 649
      top: 255
    A4:
      left: 774
      top: 391
    A5:
      left: 194
      top: 410
  Name: Book ordering
  State: Active
  StateEntityID: S1
  TransitionActions:
    - TA1
    - TA2
    - TA3
    - TA4
    - TA8
    - TA5
    - TA3
    - TA4
    - TA8
    - TA6
    - TA3
    - TA4
    - TA7
  Transitions:
    - T1
    - T2
    - T3
    - T4
    - T5
    - T6
TransitionActions:
  TA1:
    ChangeTime: 2012-11-23 16:01:37
    Config:
      Config:
        Queue: Management
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet
    CreateTime: 2012-11-23 15:50:59
    EntityID: TA1
    ID: 61
    Name: Move the process ticket into the "Management" queue
  TA2:
    ChangeTime: 2012-11-23 16:02:12
    Config:
      Config:
        Responsible: manager
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketResponsibleSet
    CreateTime: 2012-11-23 15:58:22
    EntityID: TA2
    ID: 62
    Name: Change ticket responsible to "manager"
  TA3:
    ChangeTime: 2012-11-24 14:27:02
    Config:
      Config:
        Queue: Employees
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet
    CreateTime: 2012-11-23 16:02:54
    EntityID: TA3
    ID: 63
    Name: Move the process ticket into the "Employees" queue
  TA4:
    ChangeTime: 2012-11-23 16:04:06
    Config:
      Config:
        Responsible: Employee
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketResponsibleSet
    CreateTime: 2012-11-23 16:04:06
    EntityID: TA4
    ID: 64
    Name: Change ticket responsible to "Employee"
  TA5:
    ChangeTime: 2012-12-06 02:18:34
    Config:
      Config:
        Queue: Purchasing
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet
    CreateTime: 2012-11-23 16:04:54
    EntityID: TA5
    ID: 65
    Name: Move process ticket into the "Purchasing" queue
  TA6:
    ChangeTime: 2012-12-06 02:18:48
    Config:
      Config:
        Queue: Post office
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet
    CreateTime: 2012-11-23 16:06:20
    EntityID: TA6
    ID: 66
    Name: Move process ticket into the "Post office" queue
  TA7:
    ChangeTime: 2012-12-06 02:29:55
    Config:
      Config:
        State: closed successful
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketStateSet
    CreateTime: 2012-12-06 02:29:27
    EntityID: TA7
    ID: 67
    Name: Close ticket successfully
  TA8:
    ChangeTime: 2012-12-06 02:31:12
    Config:
      Config:
        State: closed unsuccessful
      Module: Kernel::System::ProcessManagement::TransitionAction::TicketStateSet
    CreateTime: 2012-12-06 02:31:12
    EntityID: TA8
    ID: 68
    Name: Close ticket unsuccessfully
Transitions:
  T1:
    ChangeTime: 2012-11-23 15:12:20
    Config:
      Condition:
        1:
          Fields:
            DynamicField_Status:
              Match: Approval
              Type: String
          Type: and
      ConditionLinking: and
    CreateTime: 2012-11-23 11:53:52
    EntityID: T1
    ID: 94
    Name: Approval
  T2:
    ChangeTime: 2012-11-23 15:12:50
    Config:
      Condition:
        1:
          Fields:
            DynamicField_Status:
              Match: Approval denied
              Type: String
          Type: and
      ConditionLinking: and
    CreateTime: 2012-11-23 11:54:26
    EntityID: T2
    ID: 95
    Name: Approval denied
  T3:
    ChangeTime: 2012-11-23 15:13:29
    Config:
      Condition:
        1:
          Fields:
            DynamicField_Status:
              Match: Approved
              Type: String
          Type: and
      ConditionLinking: and
    CreateTime: 2012-11-23 11:54:54
    EntityID: T3
    ID: 96
    Name: Approved
  T4:
    ChangeTime: 2012-11-23 15:14:08
    Config:
      Condition:
        1:
          Fields:
            DynamicField_Status:
              Match: Order denied
              Type: String
          Type: and
      ConditionLinking: and
    CreateTime: 2012-11-23 11:55:25
    EntityID: T4
    ID: 97
    Name: Order denied
  T5:
    ChangeTime: 2012-11-23 18:30:33
    Config:
      Condition:
        1:
          Fields:
            DynamicField_Status:
              Match: Order placed
              Type: String
          Type: and
      ConditionLinking: and
    CreateTime: 2012-11-23 11:56:15
    EntityID: T5
    ID: 98
    Name: Order placed
  T6:
    ChangeTime: 2012-11-23 15:15:30
    Config:
      Condition:
        1:
          Fields:
            DynamicField_Status:
              Match: Shipment received
              Type: String
          Type: and
      ConditionLinking: and
    CreateTime: 2012-11-23 11:56:48
    EntityID: T6
    ID: 99
    Name: Shipment received

                

流程配置参考

流程

一个流程就是工作流/流程的路径。路径上的路标可以是活动或转换(后面再讨论转换)。

流程配置

流程配置可以放在文件Kernel/Config.pm中,但强烈推荐创建一个新文件如Kernel/Config/Files/MyProcess.pm。注意图形界面生成的文件为Kernel/Config/File/ZZZProcessManagement,请一定不要使用这个文件名,否则在同步流程时会被覆盖。让我们来看一个示例流程配置(从流程缓存文件):

$Self->{'Process'} = {
    'P1' => {
        Name                => 'Book order',
        CreateTime          => '16-02-2012 13:37:00',
        CreateBy            => '1',
        ChangeTime          => '17-02-2012 13:37:00',
        ChangeBy            => '1',
        State               => 'Active',
        StartActivity       => 'A1',
        StartActivityDialog => 'AD1',
        Path => {
            'A1' => {
                'T1' => {
                    ActivityEntityID => 'A2',
                },
            },
            'A2' => {
                'T2' =>  {
                    ActivityEntityID => 'A3',
                },
            },
        },
    },
    'P2' => {
        Name                => 'IT order',
        CreateTime          => '26-02-2012 13:37:00',
        CreateBy            => '1',
        ChangeTime          => '27-02-2012 13:37:00',
        ChangeBy            => '1',
        State               => 'Active',
        StartActivity       => 'A2',
        StartActivityDialog => 'AD2',
        Path => {
            'A2' => {
                'T3' => {
                    ActivityEntityID => 'A4',
                },
            },
        },
    }
};
                    

名称

流程的名称,服务人员在创建流程工单时可以选择的流程名。

创建时间

流程创建的时间。

创建人

创建流程的用户UID。

修改时间

流程被修改的时间。

修改人

最后修改流程的用户UID。

状态

定义的流程状态。可用值为:

  • ‘激活’-可以在新的流程工单中使用的所有流程。

  • ‘逐渐消失’-不能在新工单中使用,但是现有工单仍然在使用的流程。

  • ‘未激活’-流程没有激活,不能在新工单或现有工单中使用。

起始活动

当创建一个新的流程工单时,必须定义一个‘起始活动’。一旦创建了工单,这个活动就被设置并作为第一个转换检查的基础。

起始活动对话框

对新的流程工单,必须定义一个‘起始活动对话框’。这将在创建一个流程工单时显示(在选定流程后)。在这个时间点,工单还不存在,工单会在‘起始活动对话框’提交之后创建。

路径

路径包含了当前流程的活动及活动间可能的转换。还有在转换时发生的转换操作。这个方式控制了流程工单发生的路径。例如:

'A1' => {
    'T1' => {
        ActivityEntityID => 'A2',
    },
    'T2' => {
        ActivityEntityID => 'A3',
    },
    'T3' => {
        ActivityEntityID => 'A4',
        TransitionAction => ['TA1', 'TA2'],
    },
},
                    

如果一个流程工单位于活动A1,它有3个可能的方法获取另一个活动。在转换T1T3中已经定义了流程工单到移动(转换)到另一个活动必须要满足的条件。

在这个案例中,如果转换T2所需的所有流程工单及其动态字段的值都是正确的,则工单将从“活动”A1移动到> A3。 在提交了活动对话框之后,或者对工单进行了任何其他更改,将检查当前活动中是否有可能的转换。 如果可以进行多个转换,则将使用第一个转换(基于TransitionID的数值排序)。

此外,还可以在路径配置中给转换分配转换操作。这些转换操作就是在成功转换后执行的模块。在示例流程中它们用数组表单方式分配,我们会在后面讨论这些细节。

活动

活动包含一个或多个活动对话框,并模拟该流程的一个步骤。 当前活动的所有活动对话框都显示在工单详情中,可以在满足转换条件之后使用。

活动配置

让我们看一个活动配置样例:

$Self->{'Process::Activity'} =
{
    'A1' => {
        Name       => 'Activity 1 optional',
        CreateTime => '16-02-2012 13:37:00',
        CreateBy   => '1',
        ChangeTime => '17-02-2012 13:37:00',
        ChangeBy   => '1',
        ActivityDialog => {
            1 => 'AD1',
        },
    },
    'A2' => {
        Name       => 'Activity 2 optional',
        CreateTime => '16-02-2012 13:37:00',
        CreateBy   => '1',
        ChangeTime => '17-02-2012 13:37:00',
        ChangeBy   => '1',
        ActivityDialog => {
            1 => 'AD5',
            2 => 'AD6',
            3 => 'AD1',
        },
    },
};
                

名称

活动的名称。

创建时间

活动创建的时间。

创建人

创建该活动用户UID。

修改时间

最后修改的时间。

修改人

最后修改该流程的用户UID。

活动对话框

活动对话框包含当前活动的活动对话框列表。当前活动的所有活动对话框都显示在工单详情中。它们的顺序是由配置中的顺序设置的,此处AD5会显示在AD6AD1之前。

活动对话框

一个活动对话框是一个特别的屏幕,能在不同的活动中使用。

活动对话框配置

让我们看一个活动配置样例:

$Self->{'Process::ActivityDialog'} = {
    'AD1' => {
        Name             => 'ActivityDialog 1 optional',
        DescriptionShort => 'Basic info',
        DescriptionLong  => 'Please insert the necessesary basic information for IT orders',
        CreateTime       => '28-02-2012 13:37:00',
        CreateBy         => '1',
        ChangeTime       => '29-02-2012 13:37:00',
        ChangeBy         => '1',
        Fields => {
            PriorityID => {
                DescriptionShort => 'Priority ID',
                DescriptionLong  => 'Enter the priority here',
                Display          => 2,
            },
        },
        FieldOrder       => [ 'PriorityID' ],
        SubmitAdviceText => 'Note: If you submit the form...',
        SubmitButtonText => 'Send request',
    },
    'AD2' => {
        Name             => 'ActivityDialog 2 optional',
        DescriptionShort => 'Basic info',
        DescriptionLong  => 'Please insert the necessesary basic information for Book orders',
        CreateTime       => '28-02-2012 13:37:00',
        CreateBy         => '1',
        ChangeTime       => '29-02-2012 13:37:00',
        ChangeBy         => '1',
        Fields => {
            StateID => {
                DescriptionShort => 'State ID',
                DescriptionLong  => 'Enter the state here',
                Display          => 2,
                DefaultValue     => '2',
            },
            Queue => {
                DescriptionShort => 'Queue ID',
                DescriptionLong  => 'Enter the queue here',
                Display          => 2,
                DefaultValue     => 'Raw',
            },
            Title => {
                DescriptionShort => 'Title',
                DescriptionLong  => 'Enter the title here',
                Display          => 1,
                DefaultValue     => 'Default Title',
            },
            DynamicField_Anzahl => {
                DescriptionShort => 'Amount',
                DescriptionLong  => 'Enter the amount here',
                Display          => 2,
                DefaultValue     => '4',
            },
        },
        FieldOrder       => [ 'DynamicField_Anzahl', 'StateID', 'Queue', 'Title' ],
        SubmitAdviceText => 'Note: If you submit the form...',
        SubmitButtonText => 'Send request',
    },
};
                    

名称

活动对话框的名称。

创建时间

活动创建的时间。

创建人

创建该活动对话框的用户UID。

修改时间

最后修改的时间。

修改人

最后修改这个活动对话框的用户UID。

字段

包含所有能在活动对话框中显示的字段。目前能使用下列字段:

    Title
    State
    StateID
    Priority
    PriorityID
    Lock
    LockID
    Queue
    QueueID
    Customer
    CustomerID
    CustomerNo
    CustomerUserID
    Owner
    OwnerID
    Type
    TypeID
    SLA
    SLAID
    Service
    ServiceID
    Responsible
    ResponsibleID
    PendingTime
    DynamicField_$FieldName  # for all dynamic fields
                    

单个字段配置的样例:

StateID => {
    DescriptionShort => 'State ID',
    DescriptionLong  => 'Enter the state here',
    Display          => 2,
    DefaultValue     => '2',
},
                    

字段Article(信件)是一个特例。 如果它存在于 Fields(字段)配置中,则活动对话框将包含一个完整的富文本编辑器,其中包含主题字段和附件处理。 输入的文本将作为信件添加到工单。 我们来看一个示例Article(信件)字段配置:

Article => {
    DescriptionShort => 'Please insert your comment here.',
    DescriptionLong => '',
    Display         => 1,
    Config          => {
        CommunicationChannel => 'Internal'
        IsVisibleForCustomer => '0'
        LabelSubject => '',
        LabelBody    => '',
    },
},
                    

让我们看看这个字段的配置选项:

DescriptionShort(简短描述)

(可选)显示在字段标题下方的简短描述。

DescriptionLong(详细描述)

(可选)鼠标移到到字段上时显示的详细描述信息,比如怎样填写这个字段的建议。

Display(显示)

控制这个字段是否显示和/或必填,可能的值有:

  • 0:字段不可见。如果字段值应该自动设置,这就很有用。 在这种情况下,存储配置的DefaultValue(默认值)

  • 1:字段是可见的,但可选。

  • 2:字段是可见且强制的。 以下字段只能是不可见或强制性的:

        QueueID
        Queue
        State
        StateID
        Lock
        LockID
        Priority
        PriorityID
        Type
        TypeID
                                        

这个字段配置为可选的,并且用户没有提交值,当用户提交活动对话框时将使用默认值保存。

DefaultValue(默认值)

用于带 ID (如QueueID,OwnerID)的字段,这是指该值的数据库ID。 对于无 ID (如Queue、Owner)的其他字段, DefaultValue(默认值) 必须包含该值本身。 例如:

Queue => {
    DescriptionShort => 'Queue',
    DescriptionLong  => 'Enter the queue here',
    Display          => 2,
    DefaultValue     => 'Raw',
},
                        

FieldOrder(字段顺序)

在这里配置字段显示的顺序。重要:不可见字段也必须在这里配置,因为只有配置了的字段才会考虑保存,没有配置的字段不会被保存。

SubmitAdviceText(提交建议文本)

(可选)显示在提交按钮右上方的文本,提供附加的帮助或建议信息。

SubmitButtonText(提交按钮文本)

(可选)提交按钮的可定制文本。

转换

一个转换(基于配置的条件)决定使用流程中的哪一个路径,例如:一个流程工单可以移动到哪个活动对话框。

转换配置

让我们看一个转换配置的样例:

$Self->{'Process::Transition'} = {
    'T1' => {
        Name => 'Transition 1',
        CreateTime => '14-03-2012 13:37:00', # optional
        CreateBy   => '1',                   # optional
        ChangeTime => '15-03-2012 13:37:00', # optional
        ChangeBy   => '15-03-2012 13:37:00', # optional
        Condition  => {
            Cond1  => {
                Fields => {
                    StateID => {
                        Type  => 'String',
                        Match => '1',
                    },
                },
            },
        },
    },
    'T2' => {
        Name       => 'Transition 2 optional',
        CreateTime => 'DATE',   # optional
        CreateBy   => 'USERID', # optional
        ChangeTime => 'DATE',   # optional
        ChangeBy => 'USERID',   # optional
        Condition => {
            Cond1 => {
                Queue               => 'Raw',
                DynamicField_Farbe  => '2',
                DynamicField_Anzahl => '1',
            },
        },
    },
};
                    

名称

转换的名称。

创建时间

创建转换的时间。

创建人

创建转换的用户UID。

修改时间

最后修改转换的时间。

修改人

最后修改转换的用户UID。

条件

包含这个转换生效所需的所有条件。例如:

Condition => {
    Type  => 'and',
    Cond1 => {
        Type   => 'and',
        Fields => {
            StateID => {
                Type  => 'String',
                Match => '1',
            },
            DynamicField_Marke => {
                Type  => 'String',
                Match => 'VW',
        },
    },
    Cond2 => {
        Type => 'and',
        Fields => {
            Queue => {
                Type  => 'String',
                Match => 'Raw',
            },
        },
    },
},
                    

让我们看看这个条件配置的详细信息。

类型(条件)

指定不同的条件元素互相连接的方式,可能的值有:

  • and(与):这是默认值。 必须满足所有条件才能使转换生效。

  • or(或):至少有一个条件必须匹配。

  • xor(异或):必须只匹配一个条件,没有其它条件匹配。

Cond1

这是一个示例条件的名称。可以随便选择条件名称,条件按排好的顺序进行评估。

类型(条件内字段)

指定这个条件内单个字段的测试结果互相连接的方式,可能的值有:

  • and(与):这是默认值。 所有字段的测试必须都匹配此条件才能匹配。

  • or(或):至少有一个字段测试必须匹配。

  • xor(异或):必须只匹配一个字段测试,没有其它匹配。

字段

指定要测试其值的特殊字段。在我们的例子中:

Fields => {
    StateID => {
        Type  => 'String',
        Match => '1',
    },
                        

StateID

字段名的例子。可以使用下列工单字段:

    Title
    State
    StateID
    Priority
    PriorityID
    Lock
    LockID
    Queue
    QueueID
    Customer
    CustomerID
    CustomerNo
    CustomerUserID
    Owner
    OwnerID
    Type
    TypeID
    SLA
    SLAID
    Service
    ServiceID
    Responsible
    ResponsibleID
    DynamicField_$FieldName # for all DynamicFields
                        

当测试一个含有‘ID’(如SLAID)的字段时,这个字段的数据库ID将用于测试,而其它字段则使用实际值来测试。

类型

确定字段测试的类型,可能的值有:

  • String(字符串) :将字段值与 Match(匹配) 中指定的字符串进行比较,如果它们完全一样则匹配。

  • Hash(哈希):将字段值(hash)与 Match(匹配) 中指定的哈希进行比较,所有哈希值必须相同。

  • Array(数组) :将字段值(数组)与 Match(匹配) 中指定的数组进行比较, 两个列表必须相同。

  • Regex(正则表达式):可以使用正则表达式测试字段值。 重要的是, Match(匹配) 包含 qr {} xms 作为基础条件,在大括号之间才是实际的正则表达式。

  • Module(模块):允许使用perl模块进行条件检查。 如果返回1,检查结果是正的。 您可以在Kernel/System/ProcessManagement/TransitionValidation/ValidateDemo.pm中找到一个示例模块。

转换操作

转换操作是成功应用转换后触发的操作(当一个流程工单从一个活动移动到另一活动时)。这些转换操作用来对工单执行不同的变更,如变更工单的队列或所有者,你还可以创建你自己的转换操作来执行其它的复杂变更。

转换操作配置

让我们看一个转换配置的样例:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Queue Move',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet',
        Config => {
            Queue  => 'Junk',
            UserID => 123,
        },
    },
};
                    

名称

转换操作的名称。

Module(模块)

指定使用的Perl模块。

Config(配置)

这个参数包含模块所需的所有设置。它的内容取决于使用的特定的转换操作模块。请参阅单独的模块文档以了解详细信息。在我们的示例中,仅需指定队列,不过我们还需使用UserID来发送UserID参数,转换操作将使用给定的UserID来模拟用户执行。

从OTRS 3.2.4开始,所有的转换操作都可以使用 Config(配置) 参数中的UserID。 在本示例中,如果触发转换的用户没有权限将工单移动到队列 Junk ,而UserID 为123的用户可能具有此权限,这是非常重要的。

重复使用转换操作模块

要重复使用转换操作模块,只需在配置中指定多个转换操作。例如:

    $Self->{'Process::TransitionAction'} = {
        'TA1' => {
            Name   => 'Queue Move Junk',
            Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet',
            Config => {
                Queue => 'Junk',
            },
        },
        'TA2' => {
            Name   => 'Queue Move Raw',
            Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet',
            Config => {
                Queue => 'Raw',
            },
        },
    };
                    

这里使用同一个模块将流程单移动到 Raw 队列中,另一次将其移动到 junk 队列中。 必须用于特定转换的转换操作由流程配置的 Path(路径) 设置确定。

可用的转换操作

OTRS自带了多个可在你的流程中使用的转换操作。在这里你可以找到它们的文档以及需要如何配置它们。

DynamicFieldSet动态字段设置

在一个流程工单中设置一个或多个动态字段,示例:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set DynamicField MasterSlave to Master and Approved to 1',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::DynamicFieldSet',
        Config => {
            MasterSlave => 'Master',
            Approved    => '1',

        },
    },
};
                        

Name指定配置的转换操作的名称。

MasterSlaveApproved是指定动态字段名称的示例。 这两个字段的值( Master 1 )通过此转换操作设置。

TicketArticleCreate工单信件创建

创建一个信件,%DataPayload参数取决于给定的通信通道,默认情况下使用Internal(内部)。 示例:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Article Create Note',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketArticleCreate',
        Config => {

        Config                   => {
            SenderType           => 'agent',            # (required) agent|system|customer
            IsVisibleForCustomer => 1,                  # 0 or 1
            CommunicationChannel => 'Internal',         # Internal|Phone|Email|..., default: Internal

            %DataPayload,                               # some parameters depending of each communication channel
        },
    },
};
                        

下面是基于MIME的通信通道的%DataPayload(Email(电子邮件)Internal(内部)Phone(电话))。

            SenderType       => 'agent',                                                # agent|system|customer
            ContentType      => 'text/plain; charset=ISO-8859-15',                      # or optional Charset & MimeType (e.g. 'text/html; charset=UTF-8')
            Subject          => 'some short description',                               # required
            Body             => 'the message text',                                     # required
            HistoryType      => 'OwnerUpdate',                                          # EmailCustomer|Move|AddNote|PriorityUpdate|WebRequestCustomer|...
            HistoryComment   => 'Some free text!',
            From             => 'Some Agent <email@example.com>',                       # not required but useful
            To               => 'Some Customer A <customer-a@example.com>',             # not required but useful
            Cc               => 'Some Customer B <customer-b@example.com>',             # not required but useful
            ReplyTo          => 'Some Customer B <customer-b@example.com>',             # not required
            InReplyTo        => '<asdasdasd.12@example.com>',                           # not required but useful
            References       => '<asdasdasd.1@example.com> <asdasdasd.12@example.com>', # not required but useful
            NoAgentNotify    => 0,                                                      # if you don't want to send agent notifications
            AutoResponseType => 'auto reply',                                           # auto reject|auto follow up|auto reply/new ticket|auto remove

            ForceNotificationToUserID   => '1,43,56',                                    # if you want to force somebody
            ExcludeNotificationToUserID => '43,56',
                 # if you want full exclude somebody from notifications,
                 # will also be removed in To: line of article,
                 # higher prio as ForceNotificationToUserID
            ExcludeMuteNotificationToUserID => '43,56',
                 # the same as ExcludeNotificationToUserID but only the
                 # sending gets muted, agent will still shown in To:
                 # line of article
                        

Name指定配置的转换操作的名称,可以随意选择,但应反映出操作的意图。

SenderType定义信件的发件人类型,可能的值有:服务人员、系统、客户。

IsVisibleForCustomer定义信件是否应显示在客户界面中。

CommunicationChannel(通信通道)定义要创建的信件类型,可能的值有:EmailInternalPhone。还可以通过OTRS软件包安装新的通信通道来扩展此列表。

ContentType定义信件的内容类型,可能的值有: text/plain; charset=ISO-8859-15或其它任何有效的字符集和MIME类型。

Subject定义信件标题,必填。

Body定义信件的正文内容,必填。

HistoryType定义历史条目的类型,可能的值有:AddNote(添加备注)、 ArchiveFlagUpdate(归档标记更新)、 Bounce(退回)、 CustomerUpdate(客户更新)、 EmailAgent(服务人员邮件)、 EmailCustomer(客户邮件)、 EscalationResponseTimeNotifyBefore(升级响应时间通知之前)、 EscalationResponseTimeStart(升级响应时间开始)、 EscalationResponseTimeStop(升级响应时间停止)、 EscalationSolutionTimeNotifyBefore(升级解决时间通知之前)、 EscalationSolutionTimeStart(升级解决时间开始)、 EscalationSolutionTimeStop(升级解决时间停止)、 EscalationUpdateTimeNotifyBefore(升级更新时间通知之前)、 EscalationUpdateTimeStart(升级更新时间开始)、 EscalationUpdateTimeStop(升级更新时间停止)、 FollowUp(跟进)、 Forward(转发)、 Lock(锁定)、 LoopProtection(环路保护)、 Merged(合并)、 Misc(杂项)、 Move(移动)、 NewTicket(新建工单)、 OwnerUpdate(所有者更新)、 PhoneCallAgent(服务人员电话)、 PhoneCallCustomer(客户电话)、 PriorityUpdate(优先级更新)、 Remove(移除)、 ResponsibleUpdate(负责人更新)、 SendAgentNotification(发送服务人员通知)、 SendAnswer(发送答复)、 SendAutoFollowUp(发送自动跟进)、 SendAutoReject(发送自动拒绝)、 SendAutoReply(发送自动回复)、 SendCustomerNotification(发送客户通知)、 ServiceUpdate(服务更新)、 SetPendingTime(设置挂起时间)、 SLAUpdate(SLA更新)、 StateUpdate(状态更新)、 Subscribe(关注)、 SystemRequest(系统请求)、 TicketDynamicFieldUpdate(工单动态字段更新)、 TicketLinkAdd(添加工单链接)、 TicketLinkDelete(删除工单链接)、 TimeAccounting(工时管理)、 TypeUpdate(类型更新)、 Unlock(解锁)、 Unsubscribe(取消关注)、 WebRequestCustomer(客户WEB请求)。

HistoryComment定义历史条目的内容。

FromToCcReplyTo为上面指定的内容给出相应的电子邮件地址。

InReplyToReferences指定邮件消息的一些标识。

NoAgentNotify-如果设置为1,不会发送服务人员的电子邮件通知。

AutoResponseType(自动响应类型)可以是下面的值:auto follow up(自动跟进)、auto reject(自动拒绝)、auto remove(自动移除)、auto reply(自动回复)、auto reply/new ticket(自动回复/新建工单)。

ForceNotificationToUserIDExcludeNotificationToUserIDExcludeMuteNotificationToUserID用于分别指定始终会通知的UserID列表、不通知的UserID列表和列出但实际不发送通知电子邮件的UserID列表。

工单创建

创建一个有信件的工单,这个新工单能够链接到流程工单。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Ticket Create',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketCreate',
        Config => {

            # ticket required:
            Title         => 'Some Ticket Title',
            Queue         => 'Raw',              # or QueueID => 123,
            Lock          => 'unlock',
            Priority      => '3 normal',         # or PriorityID => 2,
            State         => 'new',              # or StateID => 5,
            CustomerID    => '123465',
            CustomerUser  => 'customer@example.com',
            OwnerID       => 'someuserlogin',    # or OwnerID => 123,

            # ticket optional:
            TN              => $TicketObject->TicketCreateNumber(), # optional
            Type            => 'Incident',            # or TypeID => 1, not required
            Service         => 'Service A',           # or ServiceID => 1, not required
            SLA             => 'SLA A',               # or SLAID => 1, not required
            ResponsibleID   => 123,                   # not required
            ArchiveFlag     => 'y',                   # (y|n) not required
            PendingTime     => '2011-12-23 23:05:00', # optional (for pending states)
            PendingTimeDiff => 123 ,                  # optional (for pending states)

            # article required:
            SenderType           => 'agent',           # agent|system|customer
            CommunicationChannel => 'Internal'         # Internal|Phone|Email|..., default: Internal
            IsVisibleForCustomer => '0'

            %DataPayload,                             # some parameters depending of each communication channel

            # article optional:
            TimeUnit                        => 123

            # other:
            DynamicField_NameX => $Value,
            LinkAs => $LinkType,                                        # Normal, Parent, Child, etc. (respective original ticket)
            UserID => 123,                                              # optional, to override the UserID from the logged user
        },
    },
};
                        

Name指定配置的转换操作的名称,可以随意选择,但应反映出操作的意图。

Title 工单的标题。

QueueQueueID指定用于新建工单的队列名称或ID。

LockLockID设置工单的锁定状态。

PriorityPriorityID指定用于新建工单的优先级名称或ID。

StateStateID指定用于新建工单的状态名称或ID。

CustomerID是新建工单的客户ID。

CustomerUser工单分配的客户用户登录名。

OwnerIDOwnerID指定新建工单所有者的服务人员登录名或ID。

TN是新建工单的自定义编号。

TypeTypeID 指定用于新建工单的工单类型名称或ID。

ServiceServiceID指定用于新建工单的服务名称或ID。

SLASLAID指定用于新建工单的SLA名称或ID。

ResponsibleID是新建工单负责人的服务人员ID。

PendingTime是当该工单处于一种挂起状态类型时设置工单挂起时间的一个预定义日期。

PendingTimeDiff是当该工单处于一种挂起状态类型时设置工单挂起时间的一个动态日期(从当前日期/时间开始的秒数)。

SenderType定义信件的发件人类型,可能的值有:服务人员、系统、客户。

IsVisibleForCustomer定义信件是否应显示在客户界面中。

CommunicationChannel(通信通道)定义要创建的信件类型,可能的值有:EmailInternalPhone。还可以通过OTRS软件包安装新的通信通道来扩展此列表。

请检查不同信件渠道的附加参数。

TimeUnit投入在当前工单信件的时间,以秒、分、小时等表示。

DynamicField_NameX其中DynamicField_是必需的前缀,NameX是要在新建工单中设置的动态字段的名称(在工单级别,而不是信件级别)。

LinkAs从新建工单的角度定义新工单与原工单的关系,比如普通、父、子等。

现在可以在转换操作TicketCreate中使用OTRS智能标签如<OTRS_CUSTOMER_BODY><OTRS_CUSTOMER_REALNAME>。这些智能标签可用于创建新工单,并将流程工单中的数据插入此子工单。 OTRS智能标签的用法与 TicketNotifications(工单通知) 中的文本模板相同。

TicketCustomerSet工单客户设置

设置一个流程工单的客户。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Customer Set Customer to test',
        Module => 'Kernel::System::Process::TransitionAction::TicketCustomerSet',
        Config => {
            No      => 'test',
            User    => 'client-user-123',
            # or in other words
            # CustomerID     => 'client123',
            # CustomerUserID => 'client-user-123',

        },
    },
};
                        

Name指定配置的转换操作的名称。

NoCustomerID设置客户的ID。

UserCustomerUserID设置客户的用户名。

TicketLockSet工单锁定设置

变更一个流程工单的锁定状态。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set Lock to lock',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketLockSet',
        Config => {
            Lock   => 'lock',
            # or
            LockID => 2,
        },
    },
};
                        

Name指定配置的转换操作的名称。

Lock定义该流程工单的新的锁定。

LockID定义新的锁定的内部ID。

TicketOwnerSet工单所有者设置

变更一个流程工单的所有者。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Owner Set root@localhost',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketOwnerSet',
        Config => {
            Owner => 'root@localhost',
            # or
            OwnerID => 1,
        },
    },
};
                        

Name指定配置的转换操作的名称。

Owner 指定新所有者的登录名。

OwnerID指定新所有者的内部ID。

TicketQueueSet工单队列设置

移动工单到目标队列。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Queue Move Raw',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketQueueSet',
        Config => {
            Queue => 'Raw',
            # or
            # QueueID => '2',
        },
    },
};
                        

Name指定配置的转换操作的名称。

Queue指定目标队列的名称。

QueueID指定目标队列的内部ID。

TicketResponsibleSet工单负责人设置

变更一个流程工单的负责人。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Responsible Set root@localhost',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketResponsibleSet',
        Config => {
            Responsible => 'root@localhost',
            # or
            ResponsibleID => 1,
        },
    },
};
                        

Name指定配置的转换操作的名称。

Responsible指定新负责人的登录名。

ResponsibleID指定新负责人的内部ID。

TicketServiceSet工单服务设置

给一个流程工单分配一个服务。工单必需有一个客户且该服务必须已分配给那个客户。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set MyService service',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketServiceSet',
        Config => {
            Service   => 'MyService',
            # or
            ServiceID => 123,
        },
    },
};
                        

Name指定配置的转换操作的名称。

Service定义该流程工单的新服务,需要服务全称(例如: GramdFatherService::FatherService::SonService)

ServiceID定义新服务的内部ID。

TicketSLASet工单SLA设置

给一个流程工单分配一个服务级别协议。工单需要有一个服务,SLA(服务级别协议)必须分配给那个服务。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set MySLA SLA',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketSLASet',
        Config => {
            SLA   => 'MySLA',
            # or
            SLAID => 123,
        },
    },
};
                        

Name指定配置的转换操作的名称。

SLA定义该流程工单的服务级别协议(SLA)。

SLAID定义新SLA的内部ID。

TicketStateSet工单状态设置

变更一个流程工单的状态。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set State to open',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketStateSet',
        Config => {
            State   => 'open',
            # or
            StateID => 4,

            PendingTimeDiff => 123,
        },
    },
};
                        

Name指定配置的转换操作的名称。

State定义该流程工单的新状态。

StateID定义新状态的内部ID。

PendingTimeDiff仅用于挂起类型的状态,定义相对时间秒数(相对于转换操作执行时间)来设置工单挂起时间(例如:3600意味着挂起时间是在转换操作执行后的1小时)。

TicketTitleSet工单标题设置

设置一个流程工单的标题。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set Ticket Title to Ticket-title',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketTitleSet',
        Config => {
            Title => 'Ticket-title',
        },
    },
};
                        

Name指定配置的转换操作的名称。

Title指定该工单的新标题。

TicketTypeSet工单类型设置

设置一个流程工单的工单类型。例如:

$Self->{'Process::TransitionAction'} = {
    'TA1' => {
        Name   => 'Set Ticket Type to default',
        Module => 'Kernel::System::ProcessManagement::TransitionAction::TicketTypeSet',
        Config => {
            Type     => 'default',
            # or
            # TypeID => '1',
        },
    },
};
                        

Name指定配置的转换操作的名称。

Type指定工单类型的名称。

TypeID指定工单类型的内部ID。

访问控制列表(ACL)

在ACL的帮助下,你可以在流程工单中限制可选择的值。另请参阅ACL参考以获取全部工单ACL语法的描述。

ACL 配置

只可以在文件Kernel/Config.pm中定义ACL。例如:

$Self->{TicketAcl}->{'001-ACL-ProcessProperties'} = {
    Properties => {
        Process => {
            ProcessEntityID        => ['P1'],
            ActivityEntityID       => ['A1'],
            ActivityDialogEntityID => ['AD1'],
        }
    },
    Possible => {
        ActivityDialog => ['AD1', 'AD3'],
    },
    PossibleNot => {
        ActivityDialog => ['AD3'],
    },
};
                    

001-ACL-ProcessProperties

ACL规则的名称。ACL规则的更多的信息,请查阅ACL手册

流程

这部分用于检查是否必须应用一个ACL。如果指定了值,就是应用了ACL规则,可以使用下列值:

ProcessEntityID 流程实体ID

一个流程的ID,如果工单分配到这个流程,则匹配成功。

ActivityEntityID 活动实体ID

流程工单目前分配的活动的ID。

ActivityDialogEntityID 活动对话框实体ID

一个流程工单目前打开的活动对话框的ID。

可能的/不可能的 活动对话框

在这里你可以指定活动对话框ID清单。这个清单限制了在工单详情屏幕提供给用户的可用活动对话框。

Possible列出允许的活动对话框。上述设置只允许配置的活动对话框列表中的 AD1 AD3

PossibleNot列出不允许的活动对话框。上述设置会从配置的活动对话框列表中移除AD3

如果同时指定了PossiblePossibleNot,首先通过Possible来过滤配置的活动对话框,在我们的示例中仅留下 AD1AD3。然后应用PossibleNot过滤掉AD3,所以最终只有AD1保留下来作为用户可以使用的活动对话框。

如果匹配了多个ACL规则,则计算所有匹配规则的交集来确定可能的活动对话框。例如:

已配置的活动对话框:AD1AD2AD3AD4AD5AD6AD7

$Self->{TicketAcl}->{'001-ACL-Status'} = {
    Properties => {
        Ticket => {
            Status => 'new',
        }
    },
    Possible => {
        ActivityDialog => ['AD1', 'AD2', 'AD3', 'AD6', 'AD7'],
    },
};
$Self->{TicketAcl}->{'002-ACL-Queue'} = {
    Properties => {
        Ticket => {
            Queue => ['Raw']
        }
    },
    Possible => {
        ActivityDialog => ['AD2', 'AD3', 'AD4', 'AD7'],
    },
};
$Self->{TicketAcl}->{'003-ACL-Priority'} = {
    Properties => {
        Ticket => {
            Priority => ['3 normal']
        }
    },
    PossibleNot => {
        ActivityDialog => ['AD3', 'AD4'],
    },
};
                    

如果流程工单具有状态 new ,在 Raw 队列中,并具有优先级 3 normal ,则所有三个ACL规则都将匹配。

第一条规则将活动对话框从AD1AD2AD3AD4AD5AD6AD7减少为AD1AD2AD3AD6AD7,禁用了AD4AD5

第二条规则现在将进一步减少剩余的活动对话框。 在我们的示例中,AD2AD3AD7 将保留下来。

现在,第三条规则将通过 PossibleNot 进一步减少列表。 从列表中删除 AD3 AD4 未被删除,因为它不在第一条规则的列表中。 最后, AD2 AD7 保留作为用户可以使用的活动对话框。

还可以限制在新建流程工单屏幕中显示的流程。 功能类似于限制活动对话框,除了一处不同:ACL只能基于用户。

参阅下面的示例:

$Self->{TicketAcl}->{'200-ACL-Process'} = {
    # match properties
    Properties => {
        User => {
            UserID => [2, 3],
        },
    },
    Possible => {
       Process => ['P1', 'P2', 'P3'],
    },
    PossibleNot => {
        Process => ['P4'],
    },
};
                    

$Self->{TicketAcl}->{'201-ACL-Process'} = {
    # match properties
    Properties => {
        User => {
            Group_rw => [ 'MyGroup' ],
        },
    },
    Possible => {
       Process => ['P1', 'P2', 'P3'],
    },
    PossibleNot => {
        Process => ['P4'],
    },
};
                    

$Self->{TicketAcl}->{'202-ACL-Process'} = {
    # match properties
    Properties => {
        User => {
            Role => [ 'MyRole' ],
        },
    },
    Possible => {
       Process => ['P1', 'P2', 'P3'],
    },
    PossibleNot => {
        Process => ['P4'],
    },
};
                    

导入即开即用的流程

导入

系统管理-流程管理屏幕可以找到 即开即用流程小部件,此处可以找到最佳实践的即开即用流程。当前只有一个请假申请流程可用,但可以在OTRS商业解决方案中找到更多的即开即用流程。

图 5.24. 导入即开即用流程的小部件

导入即开即用流程的小部件


在下拉菜单中选择流程,并点击导入即开即用流程按钮。流程导入后,不要忘记部署变更。

^ Use Elevator