Important

You are browsing documentation for version 5.1 of OroCommerce, supported until March 2027. Read the documentation for the latest LTS version to get up-to-date information.

See our Release Process documentation for more information on the currently supported and upcoming releases.

Workflow Transition Forms 

Configuration 

Sometimes the data in the system is not enough to progress a workflow automatically with a single button click. In such cases, users must provide additional data through UI forms — from a few fields to complex entities — before they can proceed.

You can configure a workflow transition to display a form on the UI before the transition commits, so it can handle custom data that a user provides.

The examples below illustrate common ways to configure transition forms.

Simple Example 

Suppose we have a workflow that handles only one required data input from a user.

workflows:
    greeting_flow:
        entity: Oro\Bundle\UserBundle\Entity\User
        entity_attribute: user
        defaults: { active: true }
        attributes:
            the_message:
                type: string
        steps:
            congratulated:
                allowed_transitions: [ congratulate_with ]
        transitions:
            congratulate_with:
                is_start: true
                step_to: congratulated
                form_options:
                    attribute_fields:
                        the_message:
                            options:
                                constraints:
                                    - NotBlank: ~
                destination_page: view
                transition_definition: message_definition
        transition_definitions:
            message_definition:
                actions:
                    - '@flash_message': {message: $.data.the_message, type: success}

This is a simple working example of a cycled workflow with one step and one transition.

On transition congratulate_with, the user must fill a text input in the the_message field, which corresponds to our configured workflow attribute. The constraints in the form attribute_fields options make this field required.

The user then submits the value as the transition payload. A @flash_message with the prompted text is flashed on the entity view page (the dialog is the default transition display_type).

Extended Example 

Custom types and form_init:

workflows:
    user_update_flow:
        entity: Oro\Bundle\UserBundle\Entity\User
        entity_attribute: user
        defaults: { active: true }
        attributes:
            my_message:
                type: string
            my_dote:
                type: object
                options:
                    class: DateTime
        steps:
            congratulated:
                allowed_transitions: [ congratulate_with ]
        transitions:
            congratulate_with:
                is_start: true
                step_to: congratulated
                form_options:
                    form_init:
                        - '@create_object':
                            class: \DateTime
                            attribute: $.data.my_date
                            parameters: ['tomorrow']
                    attribute_fields:
                        my_message:
                            options:
                                constraints:
                                    - NotBlank: ~
                        my_date:
                            form_type: my_date_picker #here your custom date picker
                destination_page: view
                transition_definition: message_definition
        transition_definitions:
            message_definition:
                actions:
                    - '@flash_message': {message: $my_message, type: success}

For a more complex form, specify the fields for the data you need. But first, prepare the data shown to the user in form_init.

form_init

The form_init node sits under form_options. It defines an action that runs before the form renders (see Action Component for more details), letting you prepare your data first.

In this sample configuration, a new \DateTime object is pre-configured to tomorrow, so our custom “my_date_picker” type shows the day after today predefined on the form.

Custom Form Type Example 

You can also use a custom form type for the whole transition handling. See the example below:

workflows:
    quote_update_circular:
        entity: Oro\Bundle\CustomerBundle\Entity\CustomerUser
        entity_attribute: customer_user
        defaults: {active: true}
        attributes:
           quote: #here we will store our form data result
               type:  entity
               options:
                   class: Oro\Bundle\SaleBundle\Entity\Quote
        steps:
            quote:
                allowed_transitions:
                    - transit_quote
        transitions:
            transit_quote:
                step_to: quote
                is_start: true
                transition_definition: quote_update_definition
                display_type: dialog
                form_type: 'Oro\Bundle\SaleBundle\Form\Type\QuoteType' #define a custom form type to use for transit
                form_options:
                    configuration: #define configuration for the custom form type
                        handler: 'default' #which handler should process the from (custom form transition handler)
                        template: '@OroSale/Quote/update.html.twig' #our complex form page template
                        data_provider: 'quote_update' #template context data provider that will provide data for the template
                        data_attribute: 'quote' #attribute to store form data and get from
                    form_init: #here we will prepare our form
                        - '@tree':
                            conditions: #if no quote is defined in our worfklow data ... ->
                                '@empty': [$quote]
                            actions:
                                - '@create_object': #.. -> we will create it
                                    class: Oro\Bundle\SaleBundle\Entity\Quote
                                    attribute: $.data.quote # and set to our data_attribute defined in configuration
                                    parameters: ~
                        - '@assign_value': #add some more preparation of the form data object below by WF entity data
                            attribute: $.data.quote.customerUser
                            value: $customer_user
                        - '@assign_value':
                            attribute: $.data.quote.customer
                            value: $customer_user.customer
                    attribute_fields: ~ #attribute fields should be ommited as we use totally custom form type
        transition_definitions:
            quote_update_definition:
                actions:
                    - '@flash_message':
                        message: 'Workflow transited. Entity updated!'
                        type: 'success'
                    - '@redirect': {route: 'oro_sale_quote_index'}

Here, the workflow creates a new Quote at the start on the Customer User page, then updates the Quote on each transition. Because the transition returns to the same step, these updates run circularly.

Now let’s look at some configuration specifics.

To replace the default transition form with your custom form type, set the form_type option to your custom type.

Note

Use an FQCN as the value for form_type, and make sure this form is resolvable by the “Form Registry”. You must also specify the correct configuration for the type customization (handler, template, data_provider, data_attribute options). Our example uses the Oro\Bundle\SaleBundle\Form\Type\QuoteType form type. To handle this complex form type properly, specify additional options in the form_options.configuration node.

They are:

  • handler — an alias of a service registered with the tag oro_form.registry.form_handler. Pass ‘default’ to use the default one. See more about the form update handler in Update Handler.

  • template — the name of the template to use for the custom form. The default value is @OroWorkflow/actions/update.html.twig, which you can use as a starting point for customizations.

Note

It should be extended from @OroUI/actions/update.html.twig for compatibility with transition form page (usually all Oro update templates do so).

  • data_provider — an alias of a service registered with the tag oro_form.form_template_data_provider that implements Oro\Bundle\FormBundle\Provider\FormTemplateDataProviderInterface. It should return all data the specified template needs, as controllers usually do.

  • data_attribute — the name of the data attribute that the workflow engine reads the form data payload from, passes into the form, and writes the handling result back to.

Form Reuse Recommendation 

When developing a new entity management (entity controller), the best approach is to use the Oro\Bundle\FormBundle\Model\UpdateHandlerFacade::update method.

If you encapsulate your logic into the proper parts of the form handling process, you can easily create a workflow with a custom form type. Custom form workflow transition handling is based on reusing those parts in the transition configuration.

Transition Forms and Layouts 

For layout-based sites, use the Layout Update functionality to customize the UI of a transition form.

First, make sure you are familiar with this type of interface build before you manage layout-based transition forms.

Layout Imports for New Controllers 

Several major imports can handle the following types of transition forms:

Please consider adding them to your custom transition form controller.

Context Data 

The following layout context variables are available for the transition forms:

  • workflowName — the name of a workflow

  • transitionName — the name of a transition

  • transitionFormView — the form view instance (used in rendering)

  • transition — the instance of the Transition class that the current transit corresponds to

  • workflowItem — the instance of WorkflowItem, the current workflow record representation

  • formRouteName — the route that the LayoutTransitionContext processor populates in TransitionContext

Limitations 

A workflow transition form does not have layout form provider, so you cannot reuse it in other layouts.

This is a known drawback. The transition process is complex, and reusing the transition form could make data dependency management complicated.