6.1. Starting a Process Programmatically

Below is an example of starting a service programmatically from a screen controller with roles assigned using the ProcessRuntimeService instance. This sample project is also available on GitHub.

  1. First of all, load the process definition by its code:

    ProcDefinition procDefinition = dataManager.load(
            LoadContext.create(ProcDefinition.class)
                    .setQuery(new LoadContext.Query("select pd from bpm$ProcDefinition pd where pd.code = :code")
                            .setParameter("code", PROCESS_CODE))
                    .setView("procDefinition-procInstanceEdit")
    );
  2. Next, create the process instance and associate it with the process definition and entity:

    ProcInstance procInstance = metadata.create(ProcInstance.class);
    procInstance.setProcDefinition(procDefinition);
    procInstance.setEntityId(getItem().getUuid());
    procInstance.setEntityName(getItem().getMetaClass().getName());
  3. Create process actors with the roles assigned:

    ProcActor manager = metadata.create(ProcActor.class);
    manager.setUser(userSession.getUser());
    manager.setOrder(0);
    manager.setProcInstance(procInstance);
    manager.setProcRole(procDefinition.getProcRoles().get(0));
    
    ProcActor mechanic = metadata.create(ProcActor.class);
    mechanic.setUser(getItem().getMechanic().getUser());
    mechanic.setOrder(1);
    mechanic.setProcInstance(procInstance);
    mechanic.setProcRole(procDefinition.getProcRoles().get(1));
  4. Associate the set of actors with the process instance:

    Set<ProcActor> procActors = new HashSet<>();
    procActors.add(manager);
    procActors.add(mechanic);
    
    procInstance.setProcActors(procActors);
  5. Commit created actors and process instances to the database:

    Set<Entity> committed = dataManager.commit(new CommitContext()
            .addInstanceToCommit(manager)
            .addInstanceToCommit(mechanic)
            .addInstanceToCommit(procInstance));
  6. Start the persisted process instance:

    ProcInstance committedProcInstance = (ProcInstance) committed.stream()
            .filter(p -> p.equals(procInstance))
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Error"));
    
    processRuntimeService.startProcess(committedProcInstance, "Started!", new HashMap<>());

The complete code of the startProcess() method in the screen controller invoked on a button click:

@Inject
private ProcessRuntimeService processRuntimeService;

private static String PROCESS_CODE = "orderProcessing";

public class OrderEdit extends AbstractEditor<Order> {

    public void startProcess() {
        commit();

        ProcDefinition procDefinition = dataManager.load(
                LoadContext.create(ProcDefinition.class)
                .setQuery(new LoadContext.Query("select pd from bpm$ProcDefinition pd where pd.code = :code")
                        .setParameter("code", PROCESS_CODE))
                .setView("procDefinition-procInstanceEdit")
        );

        ProcInstance procInstance = metadata.create(ProcInstance.class);
        procInstance.setProcDefinition(procDefinition);
        procInstance.setEntityId(getItem().getUuid());
        procInstance.setEntityName(getItem().getMetaClass().getName());

        Set<ProcActor> procActors = new HashSet<>();

        ProcActor manager = metadata.create(ProcActor.class);
        manager.setUser(userSession.getUser());
        manager.setOrder(0);
        manager.setProcInstance(procInstance);
        manager.setProcRole(procDefinition.getProcRoles().get(0));

        ProcActor mechanic = metadata.create(ProcActor.class);
        mechanic.setUser(getItem().getMechanic().getUser());
        mechanic.setOrder(1);
        mechanic.setProcInstance(procInstance);
        mechanic.setProcRole(procDefinition.getProcRoles().get(1));

        procActors.add(manager);
        procActors.add(mechanic);

        procInstance.setProcActors(procActors);

        Set<Entity> committed = dataManager.commit(new CommitContext()
                .addInstanceToCommit(manager)
                .addInstanceToCommit(mechanic)
                .addInstanceToCommit(procInstance));

        ProcInstance committedProcInstance = (ProcInstance) committed.stream()
                .filter(p -> p.equals(procInstance))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("Error"));

        processRuntimeService.startProcess(committedProcInstance, "Started!", new HashMap<>());

        close(COMMIT_ACTION_ID);
    }
}