PC for new employee
Description
A user has created a new request by usage of the template "Personal computer for new employee". Xurrent creates a workflow with tasks. Some of them can be cancelled depending on UI extension selections. E.g.: If the UI extension checkbox email is not checked there is no need for the email task and it can be cancelled. Do the same for all other UI extension check boxes and corresponding tasks.
Approach
On creation of the "Cancel tasks that do not need to be completed" task access all tasks of the corresponding workflow and check them against the UI extension checkbox selections of the request that is linked to the workflow. If the UI extension checkbox is not checked the corresponding task should be updated with the status canceled and the note "canceled by automation".
Prerequisites
Define the id's of the templates in the Environment variables tab. For better identification use the process prefix
$NewPC_.
Value: 22 -> $NewPC_workflow - The template Id of workflow "Personal computer for new employee".
Value: 69 -> $NewPC_tasks_cancel - The template Id of task "Cancel tasks that do not need to be completed".
Value: 70 -> $NewPC_task_pc - The template Id of task "Prepare new PC".
Value: 71 -> $NewPC_task_email - The template Id of task "Register new employee in AD and create new email account".
Value: 72 -> $NewPC_task_sap - The template Id of task "Provide SAP access".
Value: 73 -> $NewPC_task_phone - The template Id of task "Install a new fixed-line telephone".
Value: 74 -> $NewPC_task_badge - The template Id of task "Prepare a security badge".
Default values are used so solve the following problems:
- Different environemnts: E.g. template id's are different in sandbox and production. Testing is done in sandbox - after completion the package code can be transferred to production without a change, only the default values must be changed in production.
- Different packages: The same value should be used in different packages - a default value is identical in every package of an environment.
In addition the webhook must be set with following parameters:
- Account: datacenter
- Event: task.create
Commented code
// Personal Computer for new employee : automatically cancel all not required tasks
// check if the event is fired by the task with the template id $NewPC_tasks_cancel
// and the linked workflow has the template id $NewPC_workflow
// Then it is for sure that the following action inside the "if { ... }" must be done
if (task.template.id == $NewPC_tasks_cancel && task.workflow.template.id == $NewPC_workflow) {
// The workflow is linked to an other workflow manager. The api user must take over the workflow.
// get the workflow of the task into a variable to make further access shorter
let workflow = task.workflow;
// set the data that should be used for update the workflow
// in this case only the manager_id of the workflow must be updated
let workflowData = {
manager_id: apiUserId
};
// do the update of 'workflows' with $workflow.id and use $workflowData
update('workflows', workflow.id, workflowData);
// get the first request of the workflow into a variable
// if there is more than one possible each item can be referenced by an index
// the first one has the index 0, the second the index 1, ...
// for the first and the last there are helper methods (.first(), .last())
let request = workflow.requests.first();
// get the custom data of the request in a variable to make further access shorter
let custom_data = request.custom_data;
// prepare data for the updates of each task
// the status should be canceled and note should be added
let newData = {
status: 'canceled',
note: 'canceled by automation'
}
// for each task of the workflow ($workflow.tasks) perform the following actions
// inside this loop the specific task item can be accessed as task
for (let task_item of workflow.tasks) {
// Each task must be updated in different circumstances
// These are checked individually by the following if conditions
// There is one condition for each task
// This is needed since the order of the tasks in workflow.tasks is unknown
// check if the template id of the current task (task_item.template.id)
// is equal to the default value $NewPC_task_badge
// and (&&) if the badge checkbox in UI extension is NOT checked (!custom_data.badge)
if (task_item.template.id == $NewPC_task_badge && !custom_data.badge) {
update('tasks', task_item.id, newData);
}
// check if the template id of the current task (task_item.template.id)
// is equal to the default value $NewPC_task_email
// and (&&) if the email checkbox in UI extension is NOT checked (!custom_data.email)
if (task_item.template.id == $NewPC_task_email && !custom_data.email) {
update('tasks', task_item.id, newData);
}
// check if the template id of the current task (task_item.template.id)
// is equal to the default value $NewPC_task_pc
// and (&&) if the pc checkbox in UI extension is NOT checked (!custom_data.pc)
if (task_item.template.id == $NewPC_task_pc && !custom_data.pc) {
update('tasks', task_item.id, newData);
}
// check if the template id of the current task (task_item.template.id)
// is equal to the default value $NewPC_task_phone
// and (&&) if the phone checkbox in UI extension is NOT checked (!custom_data.phone)
if (task_item.template.id == $NewPC_task_phone && !custom_data.phone) {
update('tasks', task.id, newData);
}
// check if the template id of the current task (task_item.template.id)
// is equal to the default value $NewPC_task_sap
// and (&&) if the sap checkbox in UI extension is NOT checked (!custom_data.sap)
if (task_item.template.id == $NewPC_task_sap && !custom_data.sap) {
update('tasks', $item.id, newData);
}
}
// all tasks are done - now update the "automation" task to the status completed
// after that the next task that is not canceled will be assigned
newData.status = 'completed';
newData.note = 'completed by automation';
update('tasks', task.id, newData);
}
Condensed code
The comments and log entries are helpful, but make the code above quite long. Leaving them out, the code can be condensed to:
if (task.template.id == $NewPC_tasks_cancel && task.workflow.template.id == $NewPC_workflow) {
let workflow = task.workflow;
let workflowData = {
manager_id: apiUserId
};
update('workflows', workflow.id, workflowData);
let request = workflow.requests.first();
let custom_data = request.custom_data;
let newData = {
status: 'canceled',
note: 'canceled by automation'
}
for (let task_item of workflow.tasks) {
if ((task_item.template.id == $NewPC_task_badge && !custom_data.badge) ||
(task_item.template.id == $NewPC_task_email && !custom_data.email) ||
(task_item.template.id == $NewPC_task_pc && !custom_data.pc) ||
(task_item.template.id == $NewPC_task_phone && !custom_data.phone) ||
(task_item.template.id == $NewPC_task_sap && !custom_data.sap)) {
update('tasks', task_item.id, newData);
}
}
newData.status = 'completed';
newData.note = 'completed by automation';
update('tasks', task.id, newData);
}
What it does: Cancel all tasks that are not needed in a special workflow.
Working with functions
There is an alternative way to develop this with less cascading and therefore easier to read. Since the introduction of functions this is the preferred way of package development. In the main function at the beginning there are cancel conditions followed by meaningful function calls about what is happening in this package. Those functions implement the technical details. The functions get all the information they need from the main function.
(function () {
if (task.template.id != $NewPC_tasks_cancel) return;
if (task.workflow.template.id != $NewPC_workflow) return;
set_workflow_manager_to_api_user(task.workflow);
update_workflow_tasks_by_request_custom_data(task);
complete_automation_task(task);
}())
function set_workflow_manager_to_api_user(workflow) {
update('workflows', workflow.id, {
manager_id: apiUserId
});
}
function update_workflow_tasks_by_request_custom_data(task) {
let request = task.workflow.requests.first();
let custom_data = request.custom_data;
for (let task_item of workflow.tasks) {
if ((task_item.template.id == $NewPC_task_badge && !custom_data.badge) ||
(task_item.template.id == $NewPC_task_email && !custom_data.email) ||
(task_item.template.id == $NewPC_task_pc && !custom_data.pc) ||
(task_item.template.id == $NewPC_task_phone && !custom_data.phone) ||
(task_item.template.id == $NewPC_task_sap && !custom_data.sap)) {
update('tasks', task_item.id, {
status: 'canceled',
note: 'canceled by automation'
});
}
}
}
function complete_automation_task(task) {
update('tasks', task.id, {
status: 'completed',
note: 'completed by automation'
});
}