Tutorial 15: Create a workflow form with file attachment

Tutorial 15: Create a workflow form with file attachment

Introduction

In this tutorial you will learn how to create and display a task form in your workflow which contains text fields and files.

Prerequisites

In order to execute this tutorial and to get the most out of it, you should be able to answer these questions:

  1. What is a pipeline and a command and how to execute it in PIPEFORCE?

  2. What is the property store and how to save and load properties to / from it?

  3. What is a BPMN Workflow?

In case you cannot answer all of these questions, we recommend to first read the related documentation before you start this tutorial.

Step 1: Create a new app

In this step you will learn how to create the app for this tutorial.

Login to the portal at https://yourname.pipeforce.net (replace yourname by the name of your PIPEFORCE instance).

Go to LOW CODE / AUTOMATIONProperties and click Create new… App. Use the name io.pipeforce.tutorial-15-taskform for the new app.

The app config opens.

Change the title to Expenses:

"title": "Expenses",

Then save it.

Step 2: Create the form schema

In this step you will learn how to define the form fields required in the task form.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… Form Schema. Use the name expense-form for the new form schema.

Change the form schema, replace its demo content by this and save it:

{ "type": "object", "properties": { "firstName": { "type": "string", "title": "First Name", "description": "The first name of the employee." }, "lastName": { "type": "string", "title": "Last Name", "description": "The last name of the employee." }, "expenseDescription": { "type": "string", "title": "Description", "description": "Describe what the expense is for.", "maxLength": 1000 }, "expenseReceipt": { "type": "object", "title": "Receipt", "properties": { "name": {"type": "string"}, "contentLength": {"type": "number"}, "contentType": {"type": "string"}, "contentEncoding": {"type": "string"}, "content": {"type": "string"} } } } }

As you can see, our form will have four fields: first name, last name, a description about the expense and a file attachment containing the expense receipt.

This form schema describes the names and structure of the form data. In the next step we define the layout of the form.

Step 2: Create the form config

In this step you will learn how to arrange the form fields on a form.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… Form Config. Use the name expense-form for the new form config, so schema and config do have the same name.

In the first step, apply these changes to the created form config and save it:

  1. Add this line

    "type": "workflow",
  2. Remove the line

    "output": "$uri:property:global/app/io.pipeforce.tutorial-15-taskform/data/expense-form/"
  3. Add this after schema:

    "layout": { "orientation": "horizontal", "items": [ { "orientation": "vertical", "items": [ {"field": "firstName"}, {"field": "lastName"}, {"field": "expenseDescription"} ] }, { "orientation": "vertical", "items": [ {"field": "expenseReceipt", "render": "pdfviewer", "height": "628"} ] } ]

This way we have configured the form to send the output to the workflow instead of just storing it in the property store. Furthermore we changed the expense receipt to require a PDF file and this file to be displayed in the preview section of the form.

Your form config should now look similar to this:

{ "id": "c37dfc34-bd9f-4cd6-a86d-9573e15bf3e2", "title": "expense-form", "type": "workflow", "public": false, "description": "", "schema": "$uri:property:global/app/io.pipeforce.tutorial-15-taskform/schema/expense-form", "layout": { "orientation": "horizontal", "items": [ { "orientation": "vertical", "items": [ {"field": "firstName"}, {"field": "lastName"}, {"field": "expenseDescription"} ] }, { "orientation": "vertical", "items": [ {"field": "expenseReceipt", "render": "pdfviewer", "height": "628"} ] } ] } }

This will create a form layout which will look similar to this:

image-20241219-123724.png

Step 3: Create the expense workflow and task

In this step you will learn how to create a BPMN workflow with a user task in it.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… BPMN Workflow. Use the name expense-wf for the workflow.

The workflow designer opens. Create a new workflow with a start event, a user task and an end event like this and save it:

image-20241219-122218.png

Make sure to make the task a user task.

This very simple workflow will display a form to the user. After the user has filled-out this form and completed this task, the workflow ends. But you can later add a much more complex workflow here, to fit your business needs. For this tutorial we will focus on the task form only for simplicity.

Step 4: Link task to form

In this step you will learn how to link the created user task with the form config.

To do so, select the user task in the BPMN designer, go to FORM and make these selections:

  • Form Type: Custom

  • App Name: io.pipeforce.tutorial-15-taskform

  • Workflow Form: expense-form

Then click save.

Finally, your settings should look like this:

image-20241219-122741.png

Step 5: Deploy your workflow

In this step you will learn how to deploy your workflow.

What is the meaning of deploying a workflow?

To deploy a workflow means, the workflow BPMN definition will be “uploaded” into the workflow engine so workflow processes based on this definition then can be created.

In order to deploy you workflow make sure it is saved.

Then, select Deploy from the menu at the top right corner and click it:

image-20241219-131645.png

Step 5: Add a workflow start tile

In this step you will learn how to add a tile (button) which allows the user to start a new workflow by pressing this button from inside your app.

What is a tile?

A tile is a “button” which will be added to your app. Such a tile can be linked to different locations of your app such as a form, a list, a report or a workflow task for example.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… Tile. Use the name expense-wf-start for the tile.

Replace the content of the tile config by this, then save it:

{ "title": "Submit Expenses", "description": "Click here to submit your receipt.", "type": "workflow", "icon": "receipt_long", "data": "io.pipeforce.tutorial-15-taskform_expense-wf" }

Then go to Installed Apps → Expenses. There you should see your tile Submit Receipt created before, similar to this:

image-20241219-125820.png

Step 6: Start and submit your workflow via tile

In this step you will learn how to start and complete your workflow.

Then go to Installed Apps → Expenses and click the tile Submit Receipt.

This will do multiple things automatically for you:

  1. It will create a new workflow process based on your workflow definition.

  2. It will select the very first user task of the workflow and assign it to you.

  3. It opens a new tab, pre-selects the user task in the task list and shows the workflow form, ready to be filled out.

This is how the user task with your custom form will finally look like:

image-20241219-132409.png

Fill-out this task form and click COMPLETE.

Congratulations! You have successfully started a workflow with a custom form and a file attached to it.

Step 7: Retrieve the user task form data

In this you will learn how to retrieve the submitted task data in order to further process it.

Lets assume at a later state you would like to load all of these finished expense submits in order validate and further process them. You can do so by creating a pipeline for this. As an example we will create a pipeline, which iterates all submitted receipts and sends an email to the approver so he will have a look.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… Pipeline. Use the name mail-to-approver for the tile.

Replace the content of the pipeline by this and save it:

pipeline: - workflow.task.history.list: taskName: "Upload expense receipt" includeVariables: true - foreach: in: ${body} as: "expense" - mail.send: to: me@mycompany.tld subject: New expense from ${var.expense.assignee} message: | Hello, user ${var.expense.assignee} has submitted a new expense receipt.

Replace the to address by your own email address and save it.

Finally, execute this pipeline by clicking the RUN button:

image-20241219-134145.png

This will load all submitted expenses and then send and email for each.

Step 8: Listen to workflow finished event

In this tutorial you will learn to get informed in case a workflow has been finished.

In step 7 you have learned how to retrieve task data manually by calling a pipeline. But in most cases you probably want to do this step automatically: Every time the workflow was finished you would like to get immediatelly an email.

In order to reach this, you have multiple options such as for example:

  • Add a service task after the user task to your workflow and link this service task to a pipeline which sends an email.

  • Add a listener pipeline to your app which listens to workflow complete event and in this case, sends an email.

In this tutorial we will put focus on the second approach: Listening to the workflow finished event.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… Pipeline. Use the name listen-wf-finished for the new pipeline. Copy and paste this content for the pipeline. Then save it:

pipeline: - message.receive: key: pipeforce.event.workflow.end.io.pipeforce.tutorial-15-taskform.expense-wf - mail.send: to: me@mycompany.tld subject: New expense submitted message: | Hello, employee ${body.variables.firstName} ${body.variables.lastName} has submitted a new expense receipt. Click here to see details: https://${@instance.namespace()}.${@instance.domain()}/#/task

As you an see, we will listen to a message with a key structure like this:

pipeforce.event.workflow.end.{appName}.{wfName}

Whereas {appName} in our case is io.pipeforce.tutorial-15-taskform and {wfName} is expense-wf. There are more such workflow event keys you can listen for in order to automate your steps. See the docs about them: Notifications | Topics.

After you have saved this pipeline, it gets automatically activated and you will immediately receive an email every time the workflow was finished which looks like this:

image-20241226-073345.png

Step 9: Start workflow by pipeline command

In this step you will learn how to start a workflow by a command in a pipeline.

In step 6 you have learned how to start a workflow manually by clicking a tile. But sometimes it is necessary to start a workflow automatically. For example if triggered by some external actions. And for this you have to know how to start such a workflow from inside a pipeline and how to pass all required values to this workflow in order to show up in the task form.

Go to LOW CODE / AUTOMATIONProperties, select the app in the tree and click Create new… Pipeline. Use the name start-wf for the new pipeline. Copy and paste this content for the pipeline. Then save it:

vars: receiptPropertyPath: global/app/io.pipeforce.tutorial-15-taskform/data/receipt-${@date.timestamp()} pipeline: # Read receipt from cloud storage - drive.read: path: sample-invoice.pdf # Create property as data container - property.schema.put: path: ${var.receiptPropertyPath} input: "" output: false # Add attachment to data container + store result in body - property.attachment.put: path: ${var.receiptPropertyPath} # Start workflow and pass all required values as variables - workflow.start: key: io.pipeforce.tutorial-15-taskform_expense-wf claim: developer1 variables: firstName: ${@user.firstName()} lastName: ${@user.lastName()} expenseReceipt: ${body} # Read attachment from body

As you can see in this pipeline, we will download a file from the Drive cloud storage into a new data property and add it as attachment to it. Finally, we will call the command workflow.start. As key we will use the workflow definition of the workflow we would like to start. For parameter claim we will use the currently logged in user, so the the first user task in the workflow will be automatically assigned to this user. If we omit this parameter, the task is not assigned to any user initially. Finally, we wil set all initial variable values such as firstName, lastName and expenseReceipt for the first user task form. The value of expenseReceipt is a content object which is returned into the body by comand property.attachment.put.

After this pipeline has been executed, you can check in the task list for a new task with the fields firstName, lastName and expenseReceipt already prefilled, similar to this:

image-20241226-075419.png

Congrats you have done all basic steps to work with workflow forms!

 

Related content