Workflow Tasks
Once the conditions for a Workflow Rule are met, then one or more of five different types of Workflow Tasks can be stacked to fire in succession and can branch based on yes/no, success/failure or true/false decisions. The Workflow Rule sets the conditions that must be met for the Rule to be invoked, and the Tasks are the business rules that actually do something. Workflow conditions can also be set up to allow for additional flexibility.
There are five kinds of Workflow Tasks, which are explained in greater detail below. Two of these Tasks -- #Email and #Assignment are fairly straightforward and can be easily configured by non-technical users. The #Object Task can alter related data of other records and is therefore very powerful but consequently complicated. The #Extension Task is most flexible and powerful since it can execute any custom code. Additionally, there is a #Web Service Task which can call a web service in another system or on in netFORUM.
Workflow Tasks with broader applicability can be saved as a Template and can be added into multiple Workflow Rules. If and when a master Template is altered, that alteration will apply to any Workflow Rules that include the Task Template.
Managing Records
To begin setting up workflow tasks, the easiest approach is to click on the Workflow Designer link on the Workflow Rule form. Be sure that you have saved the Workflow Rule before clicking on Workflow Designer.
When the screen first opens, you will be presented with a blank Workflow Designer.
Select the Add New Task menu and you will be presented with a list of task types that can be added.
Each of these options is discussed in the sections below.
Common Fields
On all of the forms for adding tasks, there are several fields which are common. Here are the descriptions for those fields.
- make available as a template - Checking this will save this task as a template which can easily be added to other workflows. This should be used if the task is common and will be used frequently.
- start task - This box will tell NetForum that this task will be the first one to be called. Only one task should have this box checked.
- stop workflow - This box will tell NetForum that this is the end of the workflow. This task should not call another task as the workflow would end before getting to them.
- line types - This drop-down contains the options for how the next set of tasks are linked from this task. The options include Next, Success/Failure, True/False, and Yes/No. The most common line type would be Next and the task would only have a single line coming from it to the next task. The other tasks will be used more commonly when coming from code or conditions. These values would have to be set up to be returned from the code.
Send E-Mail
The option to send an e-mail will allow you to configure an e-mail to be sent to one or multiple people.
To set up the rule, from the Workflow Designer, Select Send E-Mail from the Add New Task menu. This will open the form to send an e-mail.
Sending an e-mail is done based on an existing template. The object should be the same as the object on which the workflow is based. This should be defaulted and should not need to be changed.
Once you have selected your template, you can enter the e-mail address(es) of the people who should receive the e-mail. For most objects, to send to the customer, you will enter.{{cst_eml_address_dn}}
To send to other people, simply enter their e-mail address. For multiple recipients who will be receiving the same template, you can enter multiple e-mail addresses separated by a semi-colon (;).
Assignment
The option to create an assignment will mimic the functionality of creating an assignment from the customer's record.
- Enter a task name and optionally a description.
- Choose an assignee. This will be the user in the system who will receive the assignment.
- Select an assignment role.
- Enter an assignment summary. This is a short description of the assignment.
- Select an assignment status and assignment priority.
- Enter a remind days out and due days out. These will be used to define the remind date and due date of the assignment.
- Type an assignment detail. This is a longer description of the assignment.
Once all of the information is entered, save and it will appear on the Workflow Designer.
Object
Using the Object type of Workflow Task will allow you to have another object updated based on the data being updated in the current object. There are two parts to setting up this type of task.
The first half of the setup is defining what data will be updated. This is defined by selecting the object to be updated and defining an operation. There are two options for the operation, insert and update. If insert is selected, that is all that is required on the top portion of the form. If update is selected, you will have the option of using an existing query or entering the conditions for the records to update manually. If a query is used to determine the records to be updated, the query should have no Ask At Runtime parameters. If any do exist, the default value will be used. If a query is used, the records returned will be used to determine what will be updated.
The second half of the setup is defining the values for what will be inserted or updated.
To set up the fields values to be inserted or updated, first click on the + icon. This will add a row to the grid. Select a Control To field from the first drop-down. This is a field in the object being updated or inserted. You can then either enter a Value or select a Control From. If a Value is entered, that value will be saved into the field in the first drop-down. If a Control From is entered, the value will come from the object that triggered the workflow.
You can select more values by clicking the + icon.
If a record is being inserted, all required fields in the object being inserted will need to be given a value. This can be from a combination of using the Value and Control From fields.
Program Code
A Task that executes Program Code works similarly to adding an extension to an object. This will be used to execute code that manipulates data after a record has been saved.
To set up program code as part of a workflow, the first step will be to write the code that will be called during the process. Once this code is compiled and deployed to the NetForum server, you will be able to set up the workflow.
Enter the object assembly, object type name, method to execute and the method parameters. These values will all come from the code that was written. You can use the validate method button to check that NetForum can see your code and the values are entered correctly.
There are a few special parameters which can be passed to these methods which will be picked up from the current execution context:
- Connection (connection:connection) - this is the current connection the facade object is using to complete its task
- Transaction (transaction:transaction) - this is the current transaction the facade object is using to complete its task
- Facade Object (FacadeObject:FacadeObject) - this is the current facade object which is being inserted/updated
If the program code needs to manipulate the same data which the facade object is using, these SQL statements should be run using the same connection/transaction to ensure no locking issues are encountered.
The following example illustrates a Program Code task that uses the connection, transaction, and Facade Object parameters described above. This example assumes you want your code to run in the connection and transaction existing in the object, and that if an error occurs in your code, that you want to rollback the higher-up transaction and raise an error.
This Task will execute the UpdateMovesStageHistory method contained in Avectra.netForum.Components.MM.mm_moves_opportunity in an assembly called Components. The method parameters are:
FacadeObject:FacadeObject;connection:connection;transaction:transaction
In .NET code, here is the declaration of the method. Observe how the three parameters of the method match up with the corresponding method parameters in the Task.
public void UpdateMovesStageHistoryStatus(FacadeClass oAssignment, OleDbConnection CurrentConnection, OleDbTransaction CurrentTransaction)
The FacadeClass object that Workflow will pass into this method will be the object that has just been updated. You can get values from that object to use for other operations.
In your code, take great care to manage the OleDbConnection and OleDbTransaction. A suggested template is supplied below, with code that manages the connection and transaction within two #regions, one at the beginning and one at the end. This code will use the existing Connection/Transaction if supplied, or create new ones if not supplied. Additionally, there is a section that sets Config.LastError. Do this if you want to raise an error all the way back up.
public void NameOfTheMethod(FacadeClass oFacade, OleDbConnection CurrentConnection, OleDbTransaction CurrentTransaction){ ErrorClass oEr = new ErrorClass(); #region Connection/Transaction Initialization OleDbConnection oConn; OleDbTransaction oTrans; if (CurrentConnection == null) oConn = DataUtils.GetConnection(); else oConn = CurrentConnection; if (oConn.State != ConnectionState.Open) oConn.Open(); if (CurrentTransaction == null) oTrans = oConn.BeginTransaction(); else oTrans = CurrentTransaction; #endregion // Here is where you'll execute your code oEr = DoSomething(oFacade.GetValue("xxx_key")); // Error Management: if (oEr.Number.Equals((int)ErrorClass.ErrorNumber.GeneralError)) { Config.LastError = oEr; } #region Connection/Transaction wrapup if (CurrentTransaction == null) { if (oEr.Number.Equals((int)ErrorClass.ErrorNumber.NoError)) oTrans.Commit(); else oTrans.Rollback(); } if (CurrentConnection == null) oConn.Close(); #endregion }
If the Program Code you execute should not operate within the "higher" connection and transaction, then your method should not have parameters for connection/transaction and you should create your own in your code. Do be aware that if your method fails, you will NOT be "rolling back" the overall transaction of the object that launched your workflow.
Line Type for Program Code
Workflow will evaluate the return type of the method that runs and check to see if it is a System.Boolean type. If so, and if the value is true, then the method is considered a success, else a failure. This will necessarily impact the path of True/False and Yes/No and Success/Failure connector line types.
Therefore, if you are creating methods specifically for Workflow, ensure the return value is a System.Boolean that returns true for success and false for failure.
If you're trying to call a Method that is a void, or which returns a different type, that's OK, but do realize that the only connector that can exit the Task is the Next type because the Workflow won't "know" if the result was successful or not and therefore it will default to a failure.
If an exception occurs in the code, then the Task will automatically be a Failure/No/False.
Changes in NetForum 2011.01:
Beginning in NetForum 2011.01.05, if the method returns an ErrorClass, Workflow will evaluate the ErrorNumber property. If there is no error, then the Task will is successful and the True, Yes and Success line will be followed. If there is an error, then the No, Failure or False line will be followed. If there is a Next connecting line, then that line will be followed regardless of the result of the ErrorClass.
If the method returns a Boolean type, then it will work as it always has.
If the method returns any other type, or if it is a void, then the result is considered to be Success/Yes/True, regardless of the return value (or absence of one). Previously, this would have been considered a Failure/No/False because only Boolean returns that were true were considered successful.
Web Service
Using the Web Service type of Workflow Task will allow you to update a third-party site at the same time data is being updated or inserted into NetForum.
To set up a web service task, you must enter the location for the WSDL of the web service being called. Once this is entered in the web service wsdl url field, click on the get web service methods button. This will load the drop-down below it with a list of available web services that can be called. Select the web service to be called. Selecting the web service will populate the method to execute and method parameters fields.
The final step is to define the values to be passed to the parameters. This is done on the bottom portion of the form. Click the button to add the first parameter. The Method Parameter name must match exactly with its corresponding parameter name in the method parameters of the web method.
The parameter value can be defined using either the Value field or the Control From field. The Control From field will have a list of fields available from the object that triggered the workflow.
If there is more than one parameter, click the button to add more rows for the number of parameters.
Web Services methods must be able to work with an HTTP/HTTPS Post/Get as the parameters you post are sent in this manner.
This type of Task is unable to interpret the response, if any, from the web method. Therefore, you should use the Next line type for this type of Task.
If any of these conditions are true, then you might need to work with the Program Code type of Task:
- The web service requires authentication beyond passing license keys or other information as a parameter.
- The web service's parameters include complex types that cannot be passed as a series of name/value pairs.
- You need to interpret the response of the web service and act upon the response in some way.
Condition
The final type of item that can be added is a Condition. This type of task will not affect any data by itself. This is used when the next step of a workflow is determined by data in the object that started the workflow. For example, you can have different steps based on the state or country of a new person being added. In this case, you could use conditions to filter the workflow through the appropriate steps without having to write code to handle this.
To set up a condition, you must enter a task name and select the method to execute. The following are the list of methods available.
The method parameters will need to be modified based on the data. The values to compare should replace value1 and value2 in the field. For example, if you wanted to base the flow on whether the individual had their home address in the United States versus International, you could enter the following in the field.
string:UNITED STATES;string:{ct2__cty_code}
This type of task will return either True or False and there will be two lines coming from this task to other tasks.
Beginning in 2011.03, after you choose the condition method, the condition parameters will automatically be entered into the parameters field with the appropriate data types and syntax. You will need to enter in the actual values to evaluate. Choosing DecimalGreaterThan will, for example, enter the following into method parameters:
decimal:d1;decimal:d2
You will need to replace d1 and d2 with the actual values you want to evaluate, such as:
decimal:{ind_salary};decimal:1000000
or
decimal:{xxx_approved_amount};decimal:{xxx_advanced_amount}
StringIsEmpty
Sample method parameters:
string:{coa_osh_key}
this condition will evaluate as true if the parsed value of {coa_osh_key} is empty or null. This control must exist in the Workflow Rule's Object.
StringEqualTo
Compares two strings and returns true if they are equal to each other. This comparison is case-sensitive. Do NOT use this to compare GUIDs; use StringEqualToLowerCase instead.
StringEqualToLowerCase
Compares two strings, both of which will be converted to lowercase. Use this method to compare GUID data types or other comparisons where case sensitivity is not desired.
Decimal
Use DecimalEqualTo, DecimalGreaterThan and DecimalGreaterThanOrEqualTo to evaluate two decimals. Use these condition methods for currency or numeric fields that contain decimals.
In the example above, the condition will return true if the value of the first control is greater than the value of the second control.
Date
Use DateEqualTo, DateGreaterThan and DateGreaterThanOrEqualTo to compare two dates.
In the example above, the condition above will return true if the first date is later than the second date. If the dates are the same day, of if the first date is before the second date, then the condition will return false.
These methods will ignore the time portion (if any) of the field. This is useful if you just want to compare if two fields happened on the same day but you are not concerned about the time portion of the date.
DateTime
The DateTimeEqualTo, DateTimeGreaterThan and DateTimeGreaterThanOrEqualTo are identical to the Date methods only these conditions do evaluate the time portion of the date. Be aware of this if the two dates you are comparing could occur at different times of the same day. Since most netFORUM DateTime fields do not populate the time portion of the date, you should use the Date condition methods unless you need to consider time down to the hour/minute/second. Whichever methods you choose, make sure you're aware of whether the data contain time elements in either or both fields and how that will affect the conditional operators.
BoolEqualTo
Evaluates whether two boolean values are equal to each other.
Most commonly, this condition method will be used to evaluate whether a particular checkbox is or is not checked. For example, to see if a field is checked, you would create the following condition method:
In the example above, the condition will return true if the value of the first control is 1 (which it will be if the checkbox is checked).
If you want to see if one control is equal to another, enter:
bool:{xxx_completed_flag};bool:{xxx_submitted_flag}
If both are true or both are false, then the overall condition will evaluate to true. If one is true and the other is false, then the overall condition will evaluate to false.
Note for sites before 2011.03: if you need to evaluate a boolean field, use StringIsEqual in this way, entering a 1 for true/checked or a 0 for false/unchecked:
string:{cst_credit_hold_flag};string:1
Case Study - Condition to Check When a Field's Value Exceeds a Number
This case study shows how to trigger a Workflow when an Integer value crosses a certain threshold. In this example, we want to send an email when the value of the cst_score field goes above 50, for example from 44 to 52. (You could easily change this to capture the condition of going under 50). Since there isn't a condition method for precisely this case, you'll need to stage two successive conditions. The first will see if the previous value is under 50, and the second will see if the updated value is 50 or greater.
For this case, you'll first set the Rule to fire only when cst_score changes:
Next, you'll design a Workflow with two Task conditions followed by the Task email as shown:
The first condition (the blue box in the designer screenshot above) checks to see if the original value of cst_score was less than 50. Use the asterisk in front of the field to return the original value which is the value the field was just before it was updated. See parsed values for more on this technique.
If the first condition is true, the the true line leads to the second condition Task (the middle box in the workflow designer above) which checks to see if the current value of cst_score is greater than or equal to 50:
For both condition tasks, be sure to select the int datatype in the method parameters field as shown in the images.
Technical Information
Object Model
Workflow rules fire in the FacadeClass insert or update methods, within the overall Transaction. Therefore, if you have five Tasks, and Tasks 1, 2 and 3 work but Task 4 fails, then Tasks 1, 2 and 3 will rollback. Note, however, that emails send real-time so the email cannot be recalled, and if a Task fires a web method, there is no way to un-do that.
Since Workflow uses the NetForum object model, any underlying rules are observed. For example, if a user performs an action to kick off a Workflow, and that user does not have Group Table Privileges on a particular table that a Workflow Task wants to update, then that restriction is observed and that Task will fail.
Workflow Tasks fire sequentially and are NOT asynchronous.
Tips
Start Task Condition
If your start task is a conditional with only a single True/False line, then you should try to see if you can evaluate that condition in the Workflow Rule instead of in the start task. This will make Workflow execute faster since it will evaluate this condition in the Rule and not have to get into the Tasks.
Workflow Log Table
To troubleshoot or diagnose Workflow, look into the md_workflow_task_log table, which logs the execution of each Workflow Task.
Developer Awareness
Please note that Workflow requires a high level of developer awareness. Abila has engineered certain safeties into Workflow, but with its power comes responsibility. It is easy to create Workflow that could do an infinite loop or be slow or unwieldy. You must use care in developing Workflow.
Conditions with GUIDs
If you're using StringIsEqualTo condition to compare a control with a GUID value, e.g., be aware that you can have unpredictable results due to the case-sensitivity of GUIDs. For example, this workflow task condition can evaluate to false because the parsed value of {por_d10_key} might be lowercase, which means it will never equal 73B82F7A-1F32-4D41-9591-79D6EE9956FA.
Therefore, you should change this condition to StringEqualToLowerCase.