Set an image for ConcourseSuite Community Edition

Sign In or Register

ConcourseSuite Community Edition

Core Team
PostgreSQL Java
PUBLIC PROFILE

Creating Workflows

The Centric CRM framework includes a simple, component-based rules engine that can be used asynchronously for object events (events triggered by inserting, updating, or deleting objects) or for events that occur at a scheduled point in time.

A workflow process is comprised of Java components that act as Conditions or Actions. Conditional components usually inspect an object, then decide if the result is true or false. Action components perform an action based on the object, like sending an email.

The business process workflow is defined using XML, which can be imported into a system using the Centric CRM Admin Module. The processes get cached when the application starts up and wait until triggered.

Example Workflow

The following process occurs every time a ticket is inserted or updated in Centric CRM. The workflow is designed
using Centric CRM Action Components and Condition Components. These components are included with Centric CRM. Developers can completely modify this workflow, and others, by changing rules, properties and adding custom components to do just about anything.

Workflow - Ticket Example.png

Workflow XML

Each process is defined using XML. In the base Centric CRM installation, a workflow_en_US.xml is provided, along with additional translated versions.

The workflow.xml file contains the following information:

  • Workflow Processes
  • The Objects and Actions which trigger a process
  • The Schedules which trigger a process

Defining a Workflow Process

A process has a unique name, a description, a startId which determines the first component in the process, a process type, and a module id which relates the process to a Centric CRM module for viewing online.

The following process starts with component "2" which uses the QueryTicketJustClosed component to determine if the Ticket being inserted or updated has just been closed. This component will return a "true" or "false" and any components that respond to the condition will be triggered accordingly.

<processes>
  <process name="dhv.ticket.insert" description="Ticket change notification" startId="2" 
      type="OBJECT_EVENT" module="8">
    <components>
      <component id="2" class="org.aspcfs.modules.troubletickets.components.QueryTicketJustClosed"/>
      <component id="3" parent="2" if="false" 
        class="org.aspcfs.modules.troubletickets.components.QueryTicketJustAssigned"/>
      <component id="4" parent="2" if="true" 
          class="org.aspcfs.modules.components.SendEmailNotification">
        <parameters>
          <parameter name="notification.module" value="Tickets"/>
          <parameter name="notification.itemId" value="${this.id}"/>
          <parameter name="notification.itemModified" value="${this.modified}"/>
          <parameter name="notification.userToNotify" value="${previous.enteredBy}"/>
          <parameter name="notification.userGroupToNotify" value="${previous.userGroupId}"/>
          <parameter name="notification.subject">Ticket Closed: ${this.paddedTicketId}</parameter>
          <parameter name="notification.body"><![CDATA[<strong>The following ticket in Centric CRM 
has been closed:</strong>
--- Ticket Details ---
<strong>Ticket #</strong> ${this.paddedTicketId}
Priority: ${ticketPriorityLookup.description}
Severity: ${ticketSeverityLookup.description}
Issue: ${this.problem}

Comment: ${this.comment}

Closed by: ${ticketModifiedByContact.nameFirstLast}

Solution: ${this.solution}
]]></parameter> </parameters> </component> <component id="5" parent="3" if="true" class="org.aspcfs.modules.components.SendEmailNotification"> <parameters> <parameter name="notification.module" value="Tickets"/> <parameter name="notification.itemId" value="${this.id}"/> <parameter name="notification.itemModified" value="${this.modified}"/> <parameter name="notification.userToNotify" value="${this.assignedTo}"/> <parameter name="notification.subject">Ticket Assigned: ${this.paddedTicketId}</parameter> <parameter name="notification.body"><![CDATA[<strong>The following ticket in Centric CRM has been assigned to you:</strong>

--- Ticket Details ---

<strong>Ticket #</strong> ${this.paddedTicketId}
Priority: ${ticketPriorityLookup.description}
Severity: ${ticketSeverityLookup.description}
Issue: ${this.problem}

Assigned By: ${ticketModifiedByContact.nameFirstLast}
Comment: ${this.comment}
]]></parameter> </parameters> </component> <component id="7" parent="5" if="true" class="org.aspcfs.modules.components.SendEmailNotification"> <parameters> <parameter name="notification.module" value="Tickets"/> <parameter name="notification.itemId" value="${this.id}"/> <parameter name="notification.itemModified" value="${this.modified}"/> <parameter name="notification.userGroupToNotify" value="${this.userGroupId}"/> <parameter name="notification.skipUsers" value="${this.assignedTo}"/> <parameter name="notification.subject">Ticket Assigned: ${this.paddedTicketId}</parameter> <parameter name="notification.body"><![CDATA[<strong>The following ticket in Centric CRM has been assigned to: ${ticketAssignedToContact.nameFirstLast}</strong>

--- Ticket Details ---

<strong>Ticket #</strong> ${this.paddedTicketId}
Priority: ${ticketPriorityLookup.description}
Severity: ${ticketSeverityLookup.description}
Issue: ${this.problem}

Assigned By: ${ticketModifiedByContact.nameFirstLast}
Comment: ${this.comment}
]]></parameter> </parameters> </component> <component id="6" parent="2" if="true" class="org.aspcfs.modules.troubletickets.components.SendTicketSurvey" enabled="false"/> </components> </process> </processes>

Triggering an Object Based Process

Most Centric CRM Module Action Classes call processInsertHook(), processUpdateHook(), and processDeleteHook() when their objects are modified.

The following XML will enable ticket record triggers, when a ticket is inserted or updated in any module, including the HTTP-XML API... the same process is used for insert and update in this example.

<hooks>
  <hook class="org.aspcfs.modules.troubletickets.base.Ticket" module="8">
    <actions>
      <action type="update" process="dhv.ticket.insert" enabled="true"/>
      <action type="insert" process="dhv.ticket.insert" enabled="true"/>
    </actions>
  </hook>
</hooks>

Triggering a Schedule Based Process

Scheduled processes are great when integrating with other systems or for batch notification.

To schedule a process using standard CRON terminology, the following XML will trigger a process that emails a manager when tickets have not been assigned within 10 minutes.

<schedules>
  <schedule>
    <events>
      <event process="dhv.report.ticketList.overdue" 
        second="0" minute="*/10" hour="8-18" dayOfMonth="*" month="*" dayOfWeek="*" year="*" 
        extraInfo="" businessDays="true" enabled="true"/>
    </events>
  </schedule>
</schedules>

Workflow Components

Centric CRM workflow components are Java objects intended to inspect data or act on data. As of Version 4.0, Centric CRM ships with 42 "Query" workflow components and 5 "Action" components.

Most components extend the org.aspcfs.controller.objectHookManager.ObjectHookComponent Class which provides easy access to database connections within a component, plus other useful methods. Components also implement the org.aspcfs.apps.workFlowManager.ComponentInterface.

A Simple Component

The following component checks to see if a ticket was reassigned by the user... the result for components is always boolean.

public class QueryTicketJustAssigned extends ObjectHookComponent implements ComponentInterface {

  public String getDescription() {
    return "Was the ticket just assigned or reassigned?";
  }

  public boolean execute(ComponentContext context) {
    Ticket thisTicket = (Ticket) context.getThisObject();
    Ticket previousTicket = (Ticket) context.getPreviousObject();
    if (thisTicket != null) {
      if (previousTicket != null) {
        //Ticket was updated
        return ((thisTicket.getAssignedTo() != previousTicket.getAssignedTo())
            && thisTicket.getAssignedTo() > 0);
      } else {
        //Ticket was inserted
        return (thisTicket.getAssignedTo() > 0);
      }
    }
    return false;
  }

}

Registering a Component

Centric CRM maintains a list of components in a library, which is stored in the database.

Sign in to add your comment.