> ## Documentation Index
> Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Define task Spring beans

> How to define Spring beans for custom legacy workflow task actions in Atoti Limits, using WorkflowTaskActionDTO to create UI buttons that execute tasks or display input field popups on submission

## Overview

The class `WorkflowTaskActionDTO` is used to represent a custom workflow task action.

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
public class WorkflowTaskActionDTO implements Serializable {

  /*
   * The name of the task action, which will appear as the button
   * */
  protected String name;

  /*
   *The name of the task for the custom action. This should map directly to the user task name in the BPMN process.
   * */
  @JsonProperty("taskKey")
  protected String taskName;

  /*
   * The CSS style of the button.
   * */
  protected String style;

  /*
   * True if the button should be enabled, false otherwise.
   * */
  @Builder.Default
  protected boolean enabled = true;

  /*
   * Input fields for workflow action. Used by the UI to generate  component on-the-fly.
   * */
  @Builder.Default
  protected List<WorkflowTaskActionInputFieldDTO> taskInputFields = new ArrayList<>();

  /**
   * An optional consumer to update a value of the DTO (for example if the button is enabled) that
   * accepts the current {@link UserTask} and the {@link LimitsProcessInstance} to provide current
   * information when querying the DTOs. See {@link
   * LimitsActivitiService#extractWorkflowActionsFromUserTask }
   */
  @Builder.Default
  @JsonIgnore
  protected TriConsumer<WorkflowTaskActionDTO, UserTask, LimitsProcessInstance>
      currentTaskConsumer = (wa, ut, lpi) -> {
  };
}
```

The class `WorkflowTaskActionInputFieldDTO` is defined as:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Data
@SuperBuilder(toBuilder = true)
public class WorkflowTaskActionInputFieldDTO {

    // The label of the UI field.
    protected String label;
    // The task variable used to link this input field with a backend variable.
    protected String taskVariable;
    // The input type of this field: SELECT for multiple options (a dropdown), TEST for a text input.
    protected WorkflowTaskActionInputFieldInputType inputType;
    // If this field is required by the UI for form submission.
    protected boolean required;
    // The list of options for a SELECT field. Will not be used for TEXT fields.
    @Builder.Default protected List<String> options = new ArrayList<>();
    // A value to pre-fill the input field with.
    protected String defaultValue;
}
```

where `WorkflowTaskActionInputFieldInputType` can be one of:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
public enum WorkflowTaskActionInputFieldInputType {
    SELECT, // Select multiple options from a dropdown.
    TEXT, // Input the option as a text field.
    LINK, // Input the option as a navigable link.
    CHECKBOX, // Input the option as a boolean checkbox
    ATTACHMENTS // input the option as Multipart file attachments
}
```

We have added lombok builder methods to quickly create instances of this class.

## Define the beans

Depending on the type of `WorkflowTaskActionDTO` supplied to the UI, it will render a button that on clicking will either:

* Execute an action
* Show a popup for submission and then execute an action

### 1. Execution only action

The simplest instance of a `WorkflowTaskActionDTO` will look as follows:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
    @Bean
    public WorkflowTaskActionDTO approveTaskButtonWorkflowAction(){
            return WorkflowTaskActionDTO.builder()
                .name("Approve")
                .taskName("APPROVED")
                .build();
    }
```

In this case, a button will appear on the UI with the label **Approve** and when clicked, it will submit a response to the server to execute the task specified by the task key “APPROVED”.
For more information on how the task is executed see [Executing the Java Task](./custom-workflow-action-java-code).

### 2. Popup with execution action

A more complex instance of a `WorkflowTaskActionDTO` will specify input fields to be rendered in the UI, updated and submitted to the server.
It can also provide an `defaultValue` for fields, which will pre-populate the input field in the UI. Example:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
    @Bean
    public WorkflowActionDTO reviewBreachTaskButtonWorkflowAction(){
            List<WorkflowTaskActionInputFieldDTO> inputFields = new ArrayList<>();
            WorkflowTaskActionInputFieldDTO classificationField = WorkflowTaskActionInputFieldDTO.builder()
                .label("Classification")
                .taskVariable("classification")
                .required(true)
                .inputType(SELECT)
                .options(List.of("Unclassified","Technical Issue","True Breach","New Trade","Late Trade","Market Moved"))
                .defaultValue("Unclassified")
                .build();

            final WorkflowTaskActionInputFieldDTO riskCommentField = WorkflowTaskActionInputFieldDTO.builder()
                .label("Risk comment")
                .taskVariable("riskComment")
                .inputType(TEXT)
                .build();

            inputFields.add(classificationField);
            inputFields.add(riskCommentField);

            return WorkflowTaskActionDTO.builder()
                .name(REVIEW_NAME)
                .taskName(REVIEW_KEY)
                .taskInputFields(inputFields)
                .build();
        }
```

In this example, we define two input fields: `Classification` and `Risk Comment`, with the following properties:

* `Classification` is required, so the form may not be submitted until its value is filled. `Risk Comment` is not specified as required, so it defaults to false.
* `Classification` has input type `SELECT`, so the options listed will be available in a dropdown.
* `Risk Comment` has input type `TEXT`, so a text field will appear requesting input.

## Import the beans

Once defined, the beans can then be imported into the Atoti Limits project. A nice convention is to have one `@Configuration` file per workflow, and to import these into a parent `@Configuration`.
Then, this one parent `@Configuration` can be [imported to the project](../..#importing-spring-beans-into-the-project).

For example, the out-of-the-box workflow actions are included in `WorkflowTaskActionsConfig`:

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Import({
        // Out-of-the-box workflows
        FourEyesWorkflowTaskActionsConfig.class,
        ExceptionWorkflowTaskActionsConfig.class
})
@Configuration
public class WorkflowTaskActionsConfig {

}
```

* and the `FourEyesWorkflowTaskActionConfig` class contains the tasks related to the [four eyes workflow](../../../limit-workflow#limit-process-four-eyesbpmn):

```java theme={"languages":{"custom":["/engine/python-sdk/0.9/languages/pycon.tmLanguage.json"]}}
@Configuration
public class FourEyesWorkflowTaskActionsConfig {

    @Autowired
    protected LimitsProcessInstanceWorkflowService limitsProcessInstanceWorkflowService;

    @Bean
    public WorkflowTaskActionDTO approveButtonWorkflowAction() {
        return WorkflowTaskActionDTO.builder()
                .name(APPROVED_NAME)
                .taskName(APPROVED_KEY)
                .currentTaskConsumer(createCurrentUserApprovalConsumer())
                .build();
    }

    // ....other action beans
}
```
