Zadania automatyczne

Zadania automatyczne to komponenty użytkownika, będące osobnym zadaniem w ścieżce procesu.

Stworzone zadania automatyczne dostępne są w edytorze procesów i mogą być łatwo wykorzystane w procesie biznesowym umożliwiając tym samym realizacje logiki biznesowej. Ich zachowanie może być dodatkowo konfigurowane za pomocą parametrów.

Definiowanie zadania automatycznego

Aplikacje tworzone są w oparciu o ich definicję stworzoną przez użytkownika. Definicja taka musi zawierać następujące elementy:

  1. Adnotację  (jeżeli aplikacja nie jest definiowana we wtyczce, musi ona pochodzić z pakietu com.suncode)
  2. Publiczną metodę oznaczoną adnotacją  z jednym parametrem
  3. Publiczną metodę o nazwie execute, która odpowiada za wykonanie niezbędnej logiki.

Aplikacja może również dostarczać skrypt, który buduje wygląd parametrów podczas jej definiowania w PWE. W tym celu należy dodać kolejną adnotację dla klasy  z przekazaną ścieżką do skryptu (z classpath).

Przykładowa definicja przedstawiona jest poniżej. Aplikacja wylicza wartość brutto na podstawie wartości netto i wartości VAT i ustawią ją do zmiennej podanej w parametrze.

@Application
@ComponentsFormScript( "path/example-form.js" )
public class ApplicationExample
{
    @Define
    public void definition( ApplicationDefinitionBuilder builder )
    {
        builder
            .id( "example-application" )
            .name( "application.example" )
            .description( "application.example.desc" )
            .category( Categories.TEST )
            .parameter()
                .id( "netValue" )
                .name( "application.parameter.net.name" )
                .description( "application.parameter.net.desc" )
                .type( Types.FLOAT)
                .create()
            .parameter()
                .id( "vat" )
                .name( "application.parameter.vat.name" )
                .description( "application.parameter.vat.desc" )
                .type( Types.FLOAT)
                .create()
            .parameter()
                .id( "grossValue" )
                .name( "application.parameter.gross.name" )
                .description( "application.parameter.gross.desc" )
                .type( Types.VARIABLE)
                .create();
    }
 
    public void execute( @Param Double netValue, @Param Double vat, @Param Variable grossValue )
    {
        if ( netValue == null )
        {
            return;
        }
        grossValue.setValue( netValue * vat );
    }
}

Implementacja zadania automatycznego

Zadanie automatyczne musi posiadać metodę o nazwie execute. Metoda może posiadać następujące typy parametrów:

  • pojedynczy parametr zadania automatycznego - typ parametru musi być zgodny ze zdefiniowanym typem oraz musi być poprzedzony adnotacją ,
  • parametr mapujący dwa parametry tablicowe (klucz, wartość) - typ parametru musi być typu java.util.Map<K,V>, gdzie K to zdefiniowany typ parametru komponentu będącego kluczem, a V to zdefiniowany typ parametru komponentu będącego wartością dla klucza. Parametr musi być oznaczony adnotacją  ze zdefiniowanymi właściwościami (key - id parametry będącego kluczem, value - id parametru będącego wartością).
  • pojedynczy parametr typu  oznaczony adnotacją  - jeżeli posiadamy taki typ, to wstrzyknięty zostanie obiekt DataSourceInstance na podstawie wartości tego parametru, która musi być id źródła danych.
  •  - zawiera wszystkie zdefiniowane parametry zadania automatycznego wraz z ich wartościami, jest to alternatywa dla pobierania parametru za pomocą wyżej wspomnianej adnotacji,
  •  - kontekst zadania automatycznego, można z niego odczytać identyfikator procesu i zadania,
  •  - obiekt przechowujący zmienne formularza wraz z aktualnymi wartościami oraz identyfikator procesu i zadania; wszystkim zmiennym można ustawiać wartości.
  •  - zmienne kontekstowe dostępne w tym zadaniu automatycznym. Więcej informacji tutaj,
  •  - translator dla tego komponentu, dzięki któremu wiadomości zwracane przez zadanie automatyczne mogą być tłumaczone. Więcej informacji tutaj,
  •  - obiekt zawierający informacje na temat użytkownika akceptującego zadanie.


Dostępne od wersji 3.2.44.

W momencie, gdy wywołanie zadania automatycznego nie powiedzie się, możemy wyświetlić użytkownikowi na formularzu informację z przyczyną błędu. Warunkiem jest, że akceptowane zadanie manualne nie może mieć ustawionej akceptacji równoległej (czyli odbywającej się w tle). Aby wyświetlić użytkownikowi informację należy w zadaniu automatycznym rzucić wyjątek AcceptanceException z ustawionym komunikatem błędu.

public void execute( @Param Double netValue, @Param Double vat, @Param Variable grossValue )
{
    try
	{
		grossValue.setValue( netValue * vat );
	}
	catch( Exception exception )
	{
		throw new AcceptanceException( "Nie udało się obliczyć wartości.", exception );
	}
}


Rejestracja zadania automatycznego we wtyczce

Jeżeli zadanie automatyczne jest definiowane we wtyczce to należy dodatkowo zaznaczyć, że wtyczka ta udostępnia komponenty. W tym celu należy w pliku suncode-plugin.xml dodać wpis:

<!-- Udostępnianie zadań autoamtycznych--> 
<workflow-components key="components" />

Aplikacja i klasa ustawiająca zmienne (setter) w pojedynczy komponencie


Aplikacje oraz settery praktycznie się od siebie nie różnią pod względem budowy komponentu, dlatego możliwe jest stworzenie pojedynczej definicji, która może pełnić w systemie zarówno rolę aplikacji lub settera. Definicja takiego komponentu musi mieć postać:

@Application
@VariableSetter
public class MixedComponent
{
    @Define
    public void definition( CommonDefinitionBuilder builder )
    {
        // @formatter:off
        builder
            .id( "variable-and-application-component-id" )
            .name( "variable-and-application-component-name" )
            .category( Categories.CUSTOM )
            .parameter()
                .id( "variable-and-application-param-id" )
                .name( "variable-and-application-param-name" )
                .type( Types.VARIABLE)
                .create();
        // @formatter:on
    }

    public void execute( @Param( "variable-and-application-param-id" ) Variable param )
    {
        handle( param );
    }

    public void set( @Param( "variable-and-application-param-id" ) Variable param )
    {
        handle( param );
    }

    public void handle( Variable param )
    {
        param.setValue( "some value" );
    }
}


Metoda execute zostanie wywołana, jeżeli będzie to aplikacja, set jeżeli będzie to setter. Jeżeli obie metody mają wykonywać dokładnie to samo, można wykorzystać powyższą koncepcję. Argumenty, które można przekazać do poszczególnych metod wywołujących są nadal zgodne z dokumentacjami aplikacji oraz settera.

Należy zwrócić więc uwagę, iż w aplikacji można pobrać  a w setterze . Różnią się one tylko tym, iż  zawiera nazwę akcji, która zaakceptowała zadanie. Obie klasy dziedziczą po , a więc w obu metodach set oraz execute można pobrać tego typu parametr.

 

Automatic tasks

Automatic tasks are user components that are separate tasks in the process path.

Created automatic tasks are available in the process editor and can be easily used in a business process enabling the execution of business logic. Their behavior can be additionally configured using parameters.

Defining the automatic task

Applications are created based on their definition, created by the user. Such a definition must contain the following elements:

  1. Annotation (if the application is not defined in the plugin, it must come from the com.suncode package)
  2. A public method annotated with a single parameter
  3. A public method named execute, which is responsible for executing the necessary logic.

The application can also provide a script that builds the appearance of parameters when it is defined in the PWE. To do this, add another annotation for the class  with the path to the script passed in (from classpath).

 

An example definition is shown below. The application calculates the gross value based on the net value and VAT value and will set it to the variable specified in the parameter.

@Application
@ComponentsFormScript( "path/example-form.js" )
public class ApplicationExample
{
    @Define
    public void definition( ApplicationDefinitionBuilder builder )
    {
        builder
            .id( "example-application" )
            .name( "application.example" )
            .description( "application.example.desc" )
            .category( Categories.TEST )
            .parameter()
                .id( "netValue" )
                .name( "application.parameter.net.name" )
                .description( "application.parameter.net.desc" )
                .type( Types.FLOAT)
                .create()
            .parameter()
                .id( "vat" )
                .name( "application.parameter.vat.name" )
                .description( "application.parameter.vat.desc" )
                .type( Types.FLOAT)
                .create()
            .parameter()
                .id( "grossValue" )
                .name( "application.parameter.gross.name" )
                .description( "application.parameter.gross.desc" )
                .type( Types.VARIABLE)
                .create();
    }
 
    public void execute( @Param Double netValue, @Param Double vat, @Param Variable grossValue )
    {
        if ( netValue == null )
        {
            return;
        }
        grossValue.setValue( netValue * vat );
    }
}

Implementation of an automatic task

The automatic task must have a method named execute. The method can have the following types of parameters:

  • single automatic task parameter - the type of the parameter must be consistent with the defined type and must be preceded by the annotation ,
    parameter mapping two array parameters (key, value) - the type of the parameter must be of type java.util.Map<K,V>, where K is the defined type of the component parameter being the key, and V is the defined type of the component parameter being the value for the key. The parameter must be annotated with defined properties (key - id of the parameter being the key, value - id of the parameter being the value).

  • a single parameter, type  marked with an annotation  - if you have such a type, the DataSourceInstance object will be injected based on the value of this parameter, which must be the id of the data source.
  •  - contains all the defined parameters of the automatic task with their values, this is an alternative to retrieving the parameter using the above mentioned annotation
  •  - context of the automatic task, you can read the process and task identifier from it,
  •  - an object storing the variables of the form along with their current values and the process and task identifier; all variables can be set values.
  •  - context variables available in this automated task. More info here.
  •  - ttranslator for this component, so that the messages returned by the automatic task can be translated. More info here.
  •  - object containing information about the user accepting the task.


Available from version 3.2.44.

When the call of an automatic task fails, you can display information to the user on the form with the reason for the error. The condition is that the accepted manual task cannot have a parallel acceptance set (that is, taking place in the background). In order to display the information to the user, an AcceptanceException exception must be thrown in the automatic task with the error message set.

public void execute( @Param Double netValue, @Param Double vat, @Param Variable grossValue )
{
    try
	{
		grossValue.setValue( netValue * vat );
	}
	catch( Exception exception )
	{
		throw new AcceptanceException( "Nie udało się obliczyć wartości.", exception );
	}
}


Registration of an automatic task in the plugin

If the automatic task is defined in the plugin then it is necessary to additionally indicate that the plugin provides components. To do this, add an entry in the suncode-plugin.xml file:

<!-- Sharing automatic tasks--> 
<workflow-components key="components" />

Application and class that sets variables (setter) in a single component


Applications and setters are practically no different from each other in terms of component construction, so it is possible to create a single definition that can act as both an application or a setter in the system. The definition of such a component must be of the form:

@Application
@VariableSetter
public class MixedComponent
{
    @Define
    public void definition( CommonDefinitionBuilder builder )
    {
        // @formatter:off
        builder
            .id( "variable-and-application-component-id" )
            .name( "variable-and-application-component-name" )
            .category( Categories.CUSTOM )
            .parameter()
                .id( "variable-and-application-param-id" )
                .name( "variable-and-application-param-name" )
                .type( Types.VARIABLE)
                .create();
        // @formatter:on
    }

    public void execute( @Param( "variable-and-application-param-id" ) Variable param )
    {
        handle( param );
    }

    public void set( @Param( "variable-and-application-param-id" ) Variable param )
    {
        handle( param );
    }

    public void handle( Variable param )
    {
        param.setValue( "some value" );
    }
}


The execute method will be called if it is an application; set if it is a setter. If both methods are to do exactly the same thing, you can use the above concept. The arguments that can be passed to each calling method are still in accordance with the documentation of the application and the setter.

So note that in the application you can download  in a setter  . They differ only in that it  contains the name of the action that accepted the task. Both classes inherit from , so in both set and execute methods you can retrieve this type of parameter.