Передача параметра в Бизнес-процесс

Здравствуйте!
Есть сущность Заявка, у которой есть некоторые атрибуты. У этой сущности есть свой кастомный экран редактирования. Мне нужно, чтобы при начале бизнес процесса, вместо InputDialog, где в переменные процесса можно вручную записать существующую или новую заявку, сразу открывался мой CUBA screen экран редактирования новой сущности Заявка, при коммите которой она передавалась в переменные процесса.
Из чего 2 вопроса:
1.Как правильно указать аннотации экрана редактирования чтобы в него можно было бы передать в качестве параметра переменную процесса, чтобы она устанавливалась как редактируемая сущность? Как например это происходит в:

 screenBuilders
                    .editor(Pillar.class, this)
                    .editEntity(pillar) //Здесь передается параметр
                    .withLaunchMode(OpenMode.NEW_WINDOW)
                    .build();
  1. Как реализовать создание новой сущности при открытии экрана. Аналог:
screenBuilders
                .editor(tableADPU)
                .newEntity()
                .build()

Сейчас при попытке открыть экран без параметров вылетает ошибка

java.lang.IllegalArgumentException: entity is null
	at com.haulmont.bali.util.Preconditions.checkNotNullArgument(Preconditions.java:102)
	at com.haulmont.cuba.core.global.EntityStates.isNew(EntityStates.java:65)
	at com.haulmont.cuba.gui.screen.StandardEditor.setupEntityToEdit(StandardEditor.java:179)
	at com.haulmont.cuba.gui.screen.StandardEditor.beforeShow(StandardEditor.java:104)
	at com.haulmont.bali.events.EventHub.publish(EventHub.java:170)
	at com.haulmont.cuba.gui.screen.Screen.fireEvent(Screen.java:128)
	at com.haulmont.cuba.gui.screen.UiControllerUtils.fireEvent(UiControllerUtils.java:60)
	at com.haulmont.cuba.web.sys.WebScreens.show(WebScreens.java:435)
	at com.haulmont.cuba.gui.screen.Screen.show(Screen.java:309)
	at com.haulmont.addon.bproc.web.screens.mytasks.MyTasksBrowse.onTasksTableEdit(MyTasksBrowse.java:271)
	at com.haulmont.bali.events.EventHub.publish(EventHub.java:170)
	at com.haulmont.cuba.gui.components.actions.BaseAction.actionPerform(BaseAction.java:221)
	at com.haulmont.cuba.web.gui.components.WebAbstractDataGrid.handleDoubleClickAction(WebAbstractDataGrid.java:574)
	at com.haulmont.cuba.web.gui.components.WebAbstractDataGrid.onItemClick(WebAbstractDataGrid.java:360)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:496)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:273)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:237)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1041)
	at com.vaadin.ui.Grid.access$500(Grid.java:145)
	at com.vaadin.ui.Grid$GridServerRpcImpl.itemClick(Grid.java:646)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:431)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:396)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:260)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:82)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1577)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:425)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:329)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:215)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:107)
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:93)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

Добрый день!

В проекте bproc-sampler есть пример Entity editor form, где редактор сущности используется как стартовая процессная форма и как процессная форма задачи. Посмотрите, может этот пример ответит на ваши вопросы. Немного про это написано и в документации.

Спасибо за ответ!
При попытке синхронизировать приложенный Вами пример появляется такая ошибка

Could not GET 'https://cuba-platform.bintray.com/premium/com/haulmont/addon/bproc/bproc-global/1.0.0/bproc-global-1.0.0.pom'. Received status code 401 from server: Unauthorized

При переходе по ссылке просит ввести какие то данные:
image
Что я должен сделать?

У вас должно быть, нет подписки на BProc. В readme описано как подключить триалку: https://github.com/cuba-labs/bproc-sampler#how-to-include-the-bproc-trial-version

А возможно ли вызывать выполнение задания из стороннего экрана, а не из меню BProc ->MyTasks.
Скажем в вашем же примере есть экран OrderEdit, который является обычным эдитором и который не используется в модели BProc. Я хочу из этого экрана стартовать процесс с выбранной сущностью, а при дальнейших его открытиях выполнять последующее задание. Первый пункт с заданием получается, создается процесс и назначается следующий Task. Однако следующее задание не может выполнится, вылетает NPE.
Код модифицированного OrderEdit:

@UiController("bps_Order.edit")
@UiDescriptor("order-edit.xml")
@EditedEntityContainer("orderDc")
@LoadDataBeforeShow
@ProcessForm(outcomes = {
        @Outcome(id = "approve"),
        @Outcome(id = "reject")
})
public class OrderEdit extends StandardEditor<Order> {

    @Inject
    private Metadata metadata;

    @Inject
    private ProcessFormContext processFormContext;

    @ProcessVariable
    private Order order;
    @Inject
    private BprocRuntimeService bprocRuntimeService;

    @Subscribe
    protected void onInit(InitEvent event) {
        if (processFormContext != null) {
            order = metadata.create(Order.class);
            setEntityToEdit(order);
        }
    }

    @Subscribe
    protected void onBeforeClose(BeforeCloseEvent event) {
        if (processFormContext != null) {
            CloseAction closeAction = event.getCloseAction();
            if (closeAction instanceof StandardCloseAction &&
                    Window.COMMIT_ACTION_ID.equals(((StandardCloseAction) closeAction).getActionId())) {
                Order order = getEditedEntity();
                String businessKey = order.getNumber();
                Map<String, Object> processVariables = new HashMap<>();
                processVariables.put("order", order);
                processVariables.put("approver", order.getManager());
                bprocRuntimeService.startProcessInstanceByKey("entity-editor-form",
                        businessKey,
                        processVariables); //Работает
            }
        }
    }

    public void onTaskClick() {
        if (processFormContext != null) {
            commitChanges()
                    .then(() -> {
                        processFormContext.taskCompletion()
                                .withOutcome("reject")
                                .complete(); //Не работает, NPE
                        closeWithDefaultAction();
                    });
        }
    }
}

Трейс ошибки:

ava.lang.NullPointerException
	at com.haulmont.addon.bproc.service.BprocTaskServiceBean.completeWithOutcome(BprocTaskServiceBean.java:40)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
	at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:116)
	at jdk.internal.reflect.GeneratedMethodAccessor174.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy253.completeWithOutcome(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.haulmont.cuba.core.sys.remoting.LocalServiceInvokerImpl.invoke(LocalServiceInvokerImpl.java:94)
	at com.haulmont.cuba.web.sys.remoting.LocalServiceProxy$LocalServiceInvocationHandler.invoke(LocalServiceProxy.java:154)
	at com.sun.proxy.$Proxy65.completeWithOutcome(Unknown Source)
	at com.haulmont.addon.bproc.web.processform.TaskCompletionImpl.complete(TaskCompletionImpl.java:59)
	at com.company.bps.web.screens.order.OrderEdit.lambda$onTaskClick$0(OrderEdit.java:70)
	at com.haulmont.cuba.gui.util.SuccessOperationResult.then(SuccessOperationResult.java:44)
	at com.company.bps.web.screens.order.OrderEdit.onTaskClick(OrderEdit.java:67)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.haulmont.cuba.gui.xml.DeclarativeAction.actionPerform(DeclarativeAction.java:101)
	at com.haulmont.cuba.web.gui.components.WebButton.buttonClicked(WebButton.java:64)
	at com.haulmont.cuba.web.widgets.CubaButton.fireClick(CubaButton.java:76)
	at com.vaadin.ui.Button$1.click(Button.java:57)
	at jdk.internal.reflect.GeneratedMethodAccessor294.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:431)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:396)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:260)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:82)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1577)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:425)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:329)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:215)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:107)
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:73)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:93)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

Т.е. я правильно понимаю, что редактор сущности вы не планируете открывать из стандартных экранов BProc (Start process и My Tasks). Вместо этого вы хотите открывать его обычным способом, и внутри экрана иметь кнопку запуска процесса и кнопки завершения процессных задач. Так?

Все верно!

Тогда вам не нужно использовать аннотации @ProcessForm и ProcessFormContext. Они актуальны только для “процессных форм” (когда они открываются из стандартных экранов BProc).

Вам нужно посмотреть в документации раздел BProc API.

Несколько вопросов, которые вам скорее всего придётся решить. Внутри редактора сущности вам нужно будет вычислить, есть ли связанные с данной сущностью экземпляры процесса. Если нет, то показать кнопку запуска процесса.

Потом нужно будет вычислить, есть ли задачи, назначенные на текущего пользователя и связанные с текущей сущностью. Если есть, то каким-то образом сгенерировать и показать кнопку или другие контролы, которые завершат задачу.

Подумать, может ли быть ситуация, что по текущей сущности запущено одновременно несколько процессов или для текущего пользователя по сущности имеется сразу несколько задач. Как будет выглядеть UI в этом случае. Ну и так далее.