In our company, we have a simple decision process. Each expenditure needs to be accepted by a responsible person or member of some group. Who will be that person? It depends on the type of that cost, cost center and its value:
In that case, there are two possible cost types: investment and operational. InvestAdmin approves each investment, so there is only one condition and suited result in the first row. In the next rows, cost types are blank, so that parameter is ignored. For IT Department there are two possibilities - costs with higher amount (equal or higher than 20000) are approved by one of the IT Directors, any IT Manager approves cheaper. In the end - every non-investment cost created by Board is approved by one of the board members.
All expenditures are declared via JIRA. To report costs, the concerned create new issues. After checking all data, he can proceed with a task and the approver should be designated automatically.
In a workflow, we need to add a new scriptrunner post-function. It will read a dedicated decision table and, based on it, assign to the responsible people.
Example Decision Table
In this script, we use some superclasses, which help us in code management. For more information, see the Usage of base groovy classes and utilities page.
Let's look at the script line by line.
Firstly, there is an import of required functionalities from add-ons.
Begin of PostFunction class. As you see, it extends
BaseDecisionTableWorkflowFunction, which is described later.
A constructor provides required data about workflow.
References to related fields. We strongly suggest excluding such relations to the external file, which will help you get a higher quality.
Thanks to them, we can get possible operations for all fields needed to call decision tables and process the result. Field operations allow taking no care about the particular field type in many scenarios - code is much less complex and easier to read.
Next, there is added validation, if necessary fields have values. Without them, operations could be impossible.
Build the decision table query - to declared fields in the decision table, we add values. Cost Type and Cost Center are the single choice options, so we provide the first BusinessKey (current option value). The amount is numerical, so we use ObjectValue.
Execution of query on the decision table. To get the Decision Table Operation instance, we use "costDecisions" as a name of the Decision Table file (with .dmn extension) and "costDecision" as an id of decision table element inside the DMN model because DMN can contain multiple decision tables.
Set the context related to the executed decision table. Thanks to that, we have info about the decision table name or query, which helps handle any errors.
Next, we get an entry as a map with output parameters from the result. Here we use
singleNonEmpty because we expect a single entry from the table. Other cases should be reported as incorrect.
At the finish, we fill related fields in the issue with obtained values. We use the method setValueByBusinessKey because it ensures us if important conditions are checked. For more information, see Technical documentation.
Additionally, we return
truebecause the post-function works properly.