Getting Started

Using Workflows

Updated: March 18, 2024

Learn how to manage a contract validation workflow using the REST API. Log in as different users to see the whole process and process tasks.

Hyland University
Watch the related courses on Hyland University

The contract validation workflow follows the following steps:

  1. When the workflow starts, the contract state changes to the approval and the system verifies that the amount property is filled in. If not, the workflow initiator must fill it in.
  2. A manager reviews the contract to approve it. If they reject it, the workflow initiator must fix it.
  3. When the manager approves the contract, the state changes to running.

Starting the Workflow

Goal

Start a workflow on a contract, leveraging the contract validation workflow provided by the addon Getting started with the Nuxeo Platform.

Prerequisites

Procedure

  1. Create a file called startContractValidationWorkflow.js with the following content.

    #!/usr/bin/env node
    
    let Nuxeo = require('nuxeo');
    let nuxeo = new Nuxeo({
        auth: {
            method: 'basic',
            username: 'afraser',
            password: 'afraser'
        }
    });
    let contractToFetch = '/default-domain/workspaces/North America/awesome-tech/skynet-ai-maintenance';
    nuxeo.repository()
        .fetch(contractToFetch)
        .then(contract => {
            if (contract.state !== 'draft') {
                console.log('\nSorry, the contract needs to be in the draft state to launch a validation workflow on it.\nCurrent state is: ' + contract.state + '\n');
                return;
            }
            contract.startWorkflow('BCContractValidationWf')
                .then(wf => {
                    console.log('Workflow is now started!');
                    console.log('id: ' + wf.id);
                    console.log('workflow state: ' + wf.state);
                    console.log('initiated by: ' + wf.initiator);
                })
                .catch(error => {
                    console.log('Apologies, an error occurred while starting the workflow.');
                    console.log(error);
                });
            return;
        })
        .catch(error => {
            console.log('Apologies, an error occurred while fetching the contract.');
            console.log(error);
        });
    
    
  2. Save and run:

    $ node startContractValidationWorkflow.js
    

 

Completing Tasks

Goal

Complete the Fill Amount task.

The workflow looks like this:

When the workflow started, a verification was performed that determined no amount was given in the contract properties. Therefore, a task has been assigned to the workflow initiator (Alicia Fraser in this case) so that she may fill it in before having it reviewed by a manager.

Procedure

  1. Create a file called handleUserWorkflowTasks.js with the following content. While completing a task, you can send the information filled in by a user (Alicia Fraser in this case). Here, send the contract amount.

    #!/usr/bin/env node
    
    let Nuxeo = require('nuxeo');
    let nuxeo = new Nuxeo({
      auth: {
        method: 'basic',
        username: 'afraser',
        password: 'afraser'
      }
    });
    
    // Fetch the current user's contract validation tasks
    nuxeo.workflows().fetchTasks({
        'workflowModelName': 'BCContractValidationWf'
      })
      .then(function(tasks) {
        // Display tasks
        if (tasks.length === 0) {
          console.log('No task to do! Cool!\n');
          return;
        }
        tasks.entries.forEach(currentTask => {
          console.log('Name: ' + currentTask.name);
          console.log('Status: ' + currentTask.state);
          console.log('What to do: ' + currentTask.directive);
          console.log('Before: ' + currentTask.dueDate);
          console.log('On document id: ' + currentTask.targetDocumentIds[0].id);
          console.log('Task form can be downloaded at: ' + currentTask.taskInfo.layoutResource.url);
          console.log('\nPossible actions for this task:');
          currentTask.taskInfo.taskActions.forEach(currentAction => {
            console.log('Name: ' + currentAction.name);
          });
          // Fill in the contract's amount and confirm
          currentTask
            .variable('contractAmount', '67890.99')
            .complete('confirm')
            .then(completedTask => {
              console.log('\nWe will fill in an amount and confirm to send the contract for validation.');
              console.log(`Task ${completedTask.name} is now ${completedTask.state}.`);
              // Check contract state now that the task is completed
              nuxeo.repository().fetch(completedTask.targetDocumentIds[0].id, {
                  schemas: ['bcsalescommon']
                })
                .then(contract => {
                  console.log(`Contract ${contract.title} is now in the following state: ${contract.state}.`);
                  console.log(`Its amount has been set to ${contract.properties['bcsalescommon:amount']}.`);
                });
            })
            .catch(error => {
              console.log('Apologies, an error occurred while completing a task.');
              console.log(error);
            });
        })
      })
      .catch(error => {
        console.log('Apologies, an error occurred while fetching the tasks.');
        console.log(error);
      });
    
    
  2. Save and run:

    $ node handleUserWorkflowTasks.js
    

    Note that the contract's amount has been updated.

Ending the Workflow

Goal

Review and validate the contract.

The contract should now be reviewed by a manager:

This time a task has been assigned to the managers group (represented by Sarah Connor). Validating the contract will trigger some logic and end the workflow, rejecting it will ask the workflow initiator to update it.

Procedure

  1. Create a file called handleManagerWorkflowTasks.js with the following content. Log in as Sarah Connor this time since she is a manager, and as such the one that needs to complete this task.

    #!/usr/bin/env node
    let Nuxeo = require('nuxeo');
    let nuxeo = new Nuxeo({
        auth: {
            method: 'basic',
            username: 'sconnor',
            password: 'sconnor'
        }
    });
    // Fetch the current user's contract validation tasks
    nuxeo.workflows().fetchTasks({
            'workflowModelName': 'BCContractValidationWf'
        })
        .then(function(tasks) {
            // Display tasks
            if (tasks.length === 0) {
                console.log('No task to do! Cool!\n');
                return;
            }
            tasks.entries.forEach(currentTask => {
                console.log('Name: ' + currentTask.name);
                console.log('Status: ' + currentTask.state);
                console.log('What to do: ' + currentTask.directive);
                console.log('Before: ' + currentTask.dueDate);
                console.log('On document id: ' + currentTask.targetDocumentIds[0].id);
                console.log('Task form can be downloaded at: ' + currentTask.taskInfo.layoutResource.url);
                console.log('\nPossible actions for this task:\n');
                currentTask.taskInfo.taskActions.forEach(currentAction => {
                    console.log('Name: ' + currentAction.name + '\nCan be triggered using code or by following this link:\n' + currentAction.url);
                });
                // Validate contract(s)
                currentTask.complete('validate')
                    .then(completedTask => {
                        console.log('\nWe will validate the contract.');
                        console.log('Task ' + completedTask.name + ' is now ' + completedTask.state + '.');
                        // Check contract state now that the task is completed
                        nuxeo.repository().fetch(completedTask.targetDocumentIds[0].id, {
                                schemas: ['bccontract']
                            })
                            .then(contract => {
                                console.log('Contract ' + contract.title + ' is now in the following state: ' + contract.state + '.');
                                console.log('Contract\'s expiration date has automatically been set to one year from now: ' + contract.properties['bccontract:expirationDate'] + '.');
                            });
                    })
                    .catch(error => {
                        console.log('Apologies, an error occurred while completing a task.');
                        console.log(error);
                    });
            })
        })
        .catch(error => {
            console.log('Apologies, an error occurred while fetching the tasks.');
            console.log(error);
        });
    
    
  2. Save and run:

    $ node handleManagerWorkflowTasks.js
    

    The workflow is now finished.

Notes:

  • Validating the contract triggered some logic automatically: the contract's expiration date has been set to one year from now, the contract's state is now running.
  • Instead of completing the task programmatically, you could have used direct links instead. Keep in mind that these links need to be sent using a POST call.